From 72e6f880a94250582e2e77f7a432641c893abb19 Mon Sep 17 00:00:00 2001 From: seolmin Date: Wed, 20 Dec 2023 01:53:51 +0900 Subject: [PATCH] feat: add PrivateDashboard resource in dashboard service --- src/spaceone/dashboard/info/__init__.py | 2 + .../dashboard/info/private_dashboard_info.py | 44 +++ .../info/private_dashboard_version_info.py | 52 +++ .../dashboard/interface/grpc/__init__.py | 2 + .../interface/grpc/private_dashboard.py | 119 ++++++ src/spaceone/dashboard/manager/__init__.py | 6 +- .../manager/private_dashboard_manager.py | 82 ++++ .../private_dashboard_version_manager.py | 74 ++++ .../manager/public_dashboard_manager.py | 4 +- src/spaceone/dashboard/model/__init__.py | 4 + .../model/private_dashboard_model.py | 70 ++++ .../model/private_dashboard_version_model.py | 26 ++ src/spaceone/dashboard/service/__init__.py | 1 + .../service/private_dashboard_service.py | 367 ++++++++++++++++++ .../service/public_dashboard_service.py | 34 +- 15 files changed, 866 insertions(+), 21 deletions(-) create mode 100644 src/spaceone/dashboard/info/private_dashboard_info.py create mode 100644 src/spaceone/dashboard/info/private_dashboard_version_info.py create mode 100644 src/spaceone/dashboard/interface/grpc/private_dashboard.py create mode 100644 src/spaceone/dashboard/manager/private_dashboard_manager.py create mode 100644 src/spaceone/dashboard/manager/private_dashboard_version_manager.py create mode 100644 src/spaceone/dashboard/model/private_dashboard_model.py create mode 100644 src/spaceone/dashboard/model/private_dashboard_version_model.py create mode 100644 src/spaceone/dashboard/service/private_dashboard_service.py diff --git a/src/spaceone/dashboard/info/__init__.py b/src/spaceone/dashboard/info/__init__.py index f9a3bda..c401a1d 100644 --- a/src/spaceone/dashboard/info/__init__.py +++ b/src/spaceone/dashboard/info/__init__.py @@ -1,3 +1,5 @@ from spaceone.dashboard.info.public_dashboard_info import * +from spaceone.dashboard.info.private_dashboard_info import * from spaceone.dashboard.info.public_dashboard_version_info import * +from spaceone.dashboard.info.private_dashboard_version_info import * from spaceone.dashboard.info.common_info import * diff --git a/src/spaceone/dashboard/info/private_dashboard_info.py b/src/spaceone/dashboard/info/private_dashboard_info.py new file mode 100644 index 0000000..a0d7b50 --- /dev/null +++ b/src/spaceone/dashboard/info/private_dashboard_info.py @@ -0,0 +1,44 @@ +import functools +from spaceone.api.dashboard.v1 import private_dashboard_pb2 +from spaceone.core.pygrpc.message_type import * +from spaceone.core import utils +from spaceone.dashboard.model.private_dashboard_model import PrivateDashboard + +__all__ = ["PrivateDashboardInfo", "PrivateDashboardsInfo"] + + +def PrivateDashboardInfo(dashboard_vo: PrivateDashboard, minimal=False): + info = { + "private_dashboard_id": dashboard_vo.private_dashboard_id, + "name": dashboard_vo.name, + "version": dashboard_vo.version, + "labels": change_list_value_type(dashboard_vo.labels), + "user_id": dashboard_vo.user_id, + "domain_id": dashboard_vo.domain_id, + } + + if not minimal: + info.update( + { + "layouts": change_list_value_type(dashboard_vo.layouts) + if dashboard_vo.layouts + else None, + "variables": change_struct_type(dashboard_vo.variables), + "settings": change_struct_type(dashboard_vo.settings), + "variables_schema": change_struct_type(dashboard_vo.variables_schema), + "tags": change_struct_type(dashboard_vo.tags), + "created_at": utils.datetime_to_iso8601(dashboard_vo.created_at), + "updated_at": utils.datetime_to_iso8601(dashboard_vo.updated_at), + } + ) + + return private_dashboard_pb2.PrivateDashboardInfo(**info) + + +def PrivateDashboardsInfo(dashboard_vos, total_count, **kwargs): + return private_dashboard_pb2.PrivateDashboardsInfo( + results=list( + map(functools.partial(PrivateDashboardInfo, **kwargs), dashboard_vos) + ), + total_count=total_count, + ) diff --git a/src/spaceone/dashboard/info/private_dashboard_version_info.py b/src/spaceone/dashboard/info/private_dashboard_version_info.py new file mode 100644 index 0000000..ddb3226 --- /dev/null +++ b/src/spaceone/dashboard/info/private_dashboard_version_info.py @@ -0,0 +1,52 @@ +import functools +from spaceone.api.dashboard.v1 import private_dashboard_pb2 +from spaceone.core.pygrpc.message_type import * +from spaceone.core import utils +from spaceone.dashboard.model import PrivateDashboardVersion + +__all__ = ["PrivateDashboardVersionInfo", "PrivateDashboardVersionsInfo"] + + +def PrivateDashboardVersionInfo( + dashboard_version_vo: PrivateDashboardVersion, minimal=False, latest_version=None +): + info = { + "private_dashboard_id": dashboard_version_vo.private_dashboard_id, + "version": dashboard_version_vo.version, + "created_at": utils.datetime_to_iso8601(dashboard_version_vo.created_at), + "domain_id": dashboard_version_vo.domain_id, + } + + if latest_version: + if latest_version == dashboard_version_vo.version: + info.update({"latest": True}) + else: + info.update({"latest": False}) + + if not minimal: + info.update( + { + "layouts": change_list_value_type(dashboard_version_vo.layouts) + if dashboard_version_vo.layouts + else None, + "variables": change_struct_type(dashboard_version_vo.variables), + "settings": change_struct_type(dashboard_version_vo.settings), + "variables_schema": change_struct_type( + dashboard_version_vo.variables_schema + ), + } + ) + + return private_dashboard_pb2.PrivateDashboardVersionInfo(**info) + + +def PrivateDashboardVersionsInfo(dashboard_version_vos, total_count, **kwargs): + return private_dashboard_pb2.PrivateDashboardVersionsInfo( + results=list( + map( + functools.partial(PrivateDashboardVersionInfo, **kwargs), + dashboard_version_vos, + ) + ), + total_count=total_count, + ) diff --git a/src/spaceone/dashboard/interface/grpc/__init__.py b/src/spaceone/dashboard/interface/grpc/__init__.py index f8c2f80..e517ed3 100644 --- a/src/spaceone/dashboard/interface/grpc/__init__.py +++ b/src/spaceone/dashboard/interface/grpc/__init__.py @@ -1,7 +1,9 @@ from spaceone.core.pygrpc.server import GRPCServer from spaceone.dashboard.interface.grpc.public_dashboard import PublicDashboard +from spaceone.dashboard.interface.grpc.private_dashboard import PrivateDashboard __all__ = ["app"] app = GRPCServer() app.add_service(PublicDashboard) +app.add_service(PrivateDashboard) diff --git a/src/spaceone/dashboard/interface/grpc/private_dashboard.py b/src/spaceone/dashboard/interface/grpc/private_dashboard.py new file mode 100644 index 0000000..1afc2be --- /dev/null +++ b/src/spaceone/dashboard/interface/grpc/private_dashboard.py @@ -0,0 +1,119 @@ +from spaceone.api.dashboard.v1 import private_dashboard_pb2, private_dashboard_pb2_grpc +from spaceone.core.pygrpc import BaseAPI + + +class PrivateDashboard(BaseAPI, private_dashboard_pb2_grpc.PrivateDashboardServicer): + pb2 = private_dashboard_pb2 + pb2_grpc = private_dashboard_pb2_grpc + + def create(self, request, context): + params, metadata = self.parse_request(request, context) + + with self.locator.get_service( + "PrivateDashboardService", metadata + ) as dashboard_service: + return self.locator.get_info( + "PrivateDashboardInfo", dashboard_service.create(params) + ) + + def update(self, request, context): + params, metadata = self.parse_request(request, context) + + with self.locator.get_service( + "PrivateDashboardService", metadata + ) as dashboard_service: + return self.locator.get_info( + "PrivateDashboardInfo", dashboard_service.update(params) + ) + + def delete(self, request, context): + params, metadata = self.parse_request(request, context) + + with self.locator.get_service( + "PrivateDashboardService", metadata + ) as dashboard_service: + dashboard_service.delete(params) + return self.locator.get_info("EmptyInfo") + + def get(self, request, context): + params, metadata = self.parse_request(request, context) + + with self.locator.get_service( + "PrivateDashboardService", metadata + ) as dashboard_service: + return self.locator.get_info( + "PrivateDashboardInfo", dashboard_service.get(params) + ) + + def delete_version(self, request, context): + params, metadata = self.parse_request(request, context) + + with self.locator.get_service( + "PrivateDashboardService", metadata + ) as dashboard_service: + dashboard_service.delete_version(params) + return self.locator.get_info("EmptyInfo") + + def revert_version(self, request, context): + params, metadata = self.parse_request(request, context) + + with self.locator.get_service( + "PrivateDashboardService", metadata + ) as dashboard_service: + return self.locator.get_info( + "PrivateDashboardInfo", dashboard_service.revert_version(params) + ) + + def get_version(self, request, context): + params, metadata = self.parse_request(request, context) + + with self.locator.get_service( + "PrivateDashboardService", metadata + ) as dashboard_service: + return self.locator.get_info( + "PrivateDashboardVersionInfo", + dashboard_service.get_version(params), + ) + + def list_versions(self, request, context): + params, metadata = self.parse_request(request, context) + + with self.locator.get_service( + "PrivateDashboardService", metadata + ) as dashboard_service: + ( + private_dashboard_version_vos, + total_count, + private_dashboard_version, + ) = dashboard_service.list_versions(params) + return self.locator.get_info( + "PrivateDashboardVersionsInfo", + private_dashboard_version_vos, + total_count, + minimal=self.get_minimal(params), + latest_version=private_dashboard_version, + ) + + def list(self, request, context): + params, metadata = self.parse_request(request, context) + + with self.locator.get_service( + "PrivateDashboardService", metadata + ) as dashboard_service: + private_dashboard_vos, total_count = dashboard_service.list(params) + return self.locator.get_info( + "PrivateDashboardsInfo", + private_dashboard_vos, + total_count, + minimal=self.get_minimal(params), + ) + + def stat(self, request, context): + params, metadata = self.parse_request(request, context) + + with self.locator.get_service( + "PrivateDashboardService", metadata + ) as dashboard_service: + return self.locator.get_info( + "StatisticsInfo", dashboard_service.stat(params) + ) diff --git a/src/spaceone/dashboard/manager/__init__.py b/src/spaceone/dashboard/manager/__init__.py index 4b6eca9..9b3e582 100644 --- a/src/spaceone/dashboard/manager/__init__.py +++ b/src/spaceone/dashboard/manager/__init__.py @@ -1,5 +1,9 @@ +from spaceone.dashboard.manager.identity_manager import IdentityManager from spaceone.dashboard.manager.public_dashboard_manager import PublicDashboardManager +from spaceone.dashboard.manager.private_dashboard_manager import PrivateDashboardManager from spaceone.dashboard.manager.public_dashboard_version_manager import ( PublicDashboardVersionManager, ) -from spaceone.dashboard.manager.identity_manager import IdentityManager +from spaceone.dashboard.manager.private_dashboard_version_manager import ( + PrivateDashboardVersionManager, +) diff --git a/src/spaceone/dashboard/manager/private_dashboard_manager.py b/src/spaceone/dashboard/manager/private_dashboard_manager.py new file mode 100644 index 0000000..6b0af04 --- /dev/null +++ b/src/spaceone/dashboard/manager/private_dashboard_manager.py @@ -0,0 +1,82 @@ +import logging +from spaceone.core.manager import BaseManager +from spaceone.dashboard.model.private_dashboard_model import PrivateDashboard + +_LOGGER = logging.getLogger(__name__) + + +class PrivateDashboardManager(BaseManager): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.dashboard_model: PrivateDashboard = self.locator.get_model( + "PrivateDashboard" + ) + + def create_private_dashboard(self, params: dict) -> PrivateDashboard: + def _rollback(vo: PrivateDashboard) -> None: + _LOGGER.info( + f"[create_private_dashboard._rollback] " + f"Delete vo : {vo.name} " + f"({vo.private_dashboard_id})" + ) + vo.delete() + + dashboard_vo: PrivateDashboard = self.dashboard_model.create(params) + self.transaction.add_rollback(_rollback, dashboard_vo) + + return dashboard_vo + + def update_private_dashboard(self, params: dict) -> PrivateDashboard: + dashboard_vo: PrivateDashboard = self.get_private_dashboard( + params["private_dashboard_id"], params["domain_id"] + ) + return self.update_private_dashboard_by_vo(params, dashboard_vo) + + def update_private_dashboard_by_vo( + self, params: dict, dashboard_vo: PrivateDashboard + ) -> PrivateDashboard: + def _rollback(old_data: dict) -> None: + _LOGGER.info( + f"[update_private_dashboard_by_vo._rollback] Revert Data : " + f'{old_data["private_dashboard_id"]}' + ) + dashboard_vo.update(old_data) + + self.transaction.add_rollback(_rollback, dashboard_vo.to_dict()) + return dashboard_vo.update(params) + + def delete_private_dashboard( + self, private_dashboard_id: str, domain_id: str + ) -> None: + dashboard_vo: PrivateDashboard = self.get_private_dashboard( + private_dashboard_id, domain_id + ) + dashboard_vo.delete() + + def get_private_dashboard( + self, private_dashboard_id: str, domain_id: str + ) -> PrivateDashboard: + return self.dashboard_model.get( + private_dashboard_id=private_dashboard_id, domain_id=domain_id + ) + + def list_private_dashboards(self, query: dict) -> dict: + return self.dashboard_model.query(**query) + + def stat_private_dashboards(self, query: dict) -> dict: + return self.dashboard_model.stat(**query) + + def increase_version(self, dashboard_vo: PrivateDashboard) -> None: + def _rollback(vo: PrivateDashboard): + _LOGGER.info( + f"[increase_version._rollback] Decrease Version : " + f"{vo.private_dashboard_id}" + ) + vo.decrement("version") + + dashboard_vo.increment("version") + self.transaction.add_rollback(_rollback, dashboard_vo) + + @staticmethod + def delete_by_private_dashboard_vo(dashboard_vo: PrivateDashboard) -> None: + dashboard_vo.delete() diff --git a/src/spaceone/dashboard/manager/private_dashboard_version_manager.py b/src/spaceone/dashboard/manager/private_dashboard_version_manager.py new file mode 100644 index 0000000..5f50c3e --- /dev/null +++ b/src/spaceone/dashboard/manager/private_dashboard_version_manager.py @@ -0,0 +1,74 @@ +import logging +from spaceone.core.manager import BaseManager +from spaceone.dashboard.model import PrivateDashboardVersion +from spaceone.dashboard.model import PrivateDashboard + +_LOGGER = logging.getLogger(__name__) + + +class PrivateDashboardVersionManager(BaseManager): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.version_model: PrivateDashboardVersion = self.locator.get_model( + "DashboardVersion" + ) + + def create_version_by_private_dashboard_vo( + self, dashboard_vo: PrivateDashboard, params: dict + ) -> PrivateDashboardVersion: + def _rollback(vo: PrivateDashboardVersion) -> None: + _LOGGER.info( + f"[create_private_dashboard_version._rollback] " + f"Delete private_dashboard_version_vo : {vo.version} " + f"({vo.private_dashboard_id})" + ) + vo.delete() + + new_params = { + "private_dashboard_id": dashboard_vo.private_dashboard_id, + "version": dashboard_vo.version, + "layouts": params.get("layouts") + if params.get("layouts") + else dashboard_vo.layouts, + "variables": params.get("variables") + if params.get("variables") + else dashboard_vo.variables, + "settings": params.get("settings") + if params.get("settings") + else dashboard_vo.settings, + "variables_schema": params.get("variables_schema") + if params.get("variables_schema") + else dashboard_vo.variables_schema, + "domain_id": dashboard_vo.domain_id, + } + + version_vo: PrivateDashboardVersion = self.version_model.create(new_params) + self.transaction.add_rollback(_rollback, version_vo) + return version_vo + + def delete_version( + self, private_dashboard_id: str, version: int, domain_id: str + ) -> None: + version_vo: PrivateDashboardVersion = self.get_version( + private_dashboard_id, version, domain_id + ) + version_vo.delete() + + @staticmethod + def delete_versions_by_private_dashboard_version_vos(private_dashboard_version_vos): + private_dashboard_version_vos.delete() + + def get_version(self, private_dashboard_id, version, domain_id): + return self.version_model.get( + private_dashboard_id=private_dashboard_id, + version=version, + domain_id=domain_id, + ) + + def list_versions(self, query: dict = None) -> dict: + if query is None: + query = {} + return self.version_model.query(**query) + + def filter_versions(self, **conditions) -> dict: + return self.version_model.filter(**conditions) diff --git a/src/spaceone/dashboard/manager/public_dashboard_manager.py b/src/spaceone/dashboard/manager/public_dashboard_manager.py index 87a3d6b..b215168 100644 --- a/src/spaceone/dashboard/manager/public_dashboard_manager.py +++ b/src/spaceone/dashboard/manager/public_dashboard_manager.py @@ -71,9 +71,7 @@ def get_public_dashboard( return self.dashboard_model.get(**conditions) - def list_public_dashboards(self, query=None): - if query is None: - query = {} + def list_public_dashboards(self, query: dict) -> dict: return self.dashboard_model.query(**query) def stat_public_dashboards(self, query: dict) -> dict: diff --git a/src/spaceone/dashboard/model/__init__.py b/src/spaceone/dashboard/model/__init__.py index 4b7b323..519c1a1 100644 --- a/src/spaceone/dashboard/model/__init__.py +++ b/src/spaceone/dashboard/model/__init__.py @@ -1,4 +1,8 @@ from spaceone.dashboard.model.public_dashboard_model import PublicDashboard +from spaceone.dashboard.model.private_dashboard_model import PrivateDashboard from spaceone.dashboard.model.public_dashboard_version_model import ( PublicDashboardVersion, ) +from spaceone.dashboard.model.private_dashboard_version_model import ( + PrivateDashboardVersion, +) diff --git a/src/spaceone/dashboard/model/private_dashboard_model.py b/src/spaceone/dashboard/model/private_dashboard_model.py new file mode 100644 index 0000000..bc5dea0 --- /dev/null +++ b/src/spaceone/dashboard/model/private_dashboard_model.py @@ -0,0 +1,70 @@ +from mongoengine import * +from spaceone.core.error import ERROR_NOT_UNIQUE + +from spaceone.core.model.mongo_model import MongoModel + + +class PrivateDashboard(MongoModel): + private_dashboard_id = StringField( + max_length=40, generate_id="private-dash", unique=True + ) + name = StringField(max_length=100) + version = IntField(default=1) + layouts = ListField(default=[]) + variables = DictField(default={}) + settings = DictField(default={}) + variables_schema = DictField(default={}) + labels = ListField(StringField()) + tags = DictField(default={}) + user_id = StringField(max_length=40) + domain_id = StringField(max_length=40) + created_at = DateTimeField(auto_now_add=True) + updated_at = DateTimeField(auto_now=True) + + meta = { + "updatable_fields": [ + "name", + "layouts", + "variables", + "settings", + "variables_schema", + "labels", + "tags", + ], + "minimal_fields": [ + "private_dashboard_id", + "name", + "version", + "user_id", + "domain_id", + ], + "ordering": ["name"], + "indexes": [ + "name", + "labels", + "user_id", + "domain_id", + ], + } + + @classmethod + def create(cls, data): + dashboard_vos = cls.filter(name=data["name"], domain_id=data["domain_id"]) + + if dashboard_vos.count() > 0: + raise ERROR_NOT_UNIQUE(key="name", value=data["name"]) + return super().create(data) + + def update(self, data): + if "name" in data: + dashboard_vos = self.filter( + name=data["name"], + domain_id=self.domain_id, + private_dashboard_id__ne=self.private_dashboard_id, + ) + + if dashboard_vos.count() > 0: + raise ERROR_NOT_UNIQUE(key="name", value=data["name"]) + else: + return super().update(data) + return super().update(data) diff --git a/src/spaceone/dashboard/model/private_dashboard_version_model.py b/src/spaceone/dashboard/model/private_dashboard_version_model.py new file mode 100644 index 0000000..e8ec7ca --- /dev/null +++ b/src/spaceone/dashboard/model/private_dashboard_version_model.py @@ -0,0 +1,26 @@ +from mongoengine import * + +from spaceone.core.model.mongo_model import MongoModel + + +class PrivateDashboardVersion(MongoModel): + private_dashboard_id = StringField(max_length=40) + version = IntField() + layouts = ListField(default=[]) + variables = DictField(default={}) + settings = DictField(default={}) + variables_schema = DictField(default={}) + domain_id = StringField(max_length=40) + created_at = DateTimeField(auto_now_add=True) + + meta = { + "updatable_fields": [], + "minimal_fields": [ + "private_dashboard_id", + "version", + "domain_id", + "created_at", + ], + "ordering": ["-version"], + "indexes": ["private_dashboard_id", "version", "domain_id", "created_at"], + } diff --git a/src/spaceone/dashboard/service/__init__.py b/src/spaceone/dashboard/service/__init__.py index 11119ef..99ca26e 100644 --- a/src/spaceone/dashboard/service/__init__.py +++ b/src/spaceone/dashboard/service/__init__.py @@ -1 +1,2 @@ from spaceone.dashboard.service.public_dashboard_service import PublicDashboardService +from spaceone.dashboard.service.private_dashboard_service import PrivateDashboardService diff --git a/src/spaceone/dashboard/service/private_dashboard_service.py b/src/spaceone/dashboard/service/private_dashboard_service.py new file mode 100644 index 0000000..aad9471 --- /dev/null +++ b/src/spaceone/dashboard/service/private_dashboard_service.py @@ -0,0 +1,367 @@ +import copy +import logging + +from spaceone.core.service import * +from spaceone.dashboard.manager import ( + PrivateDashboardManager, + PrivateDashboardVersionManager, + IdentityManager, +) +from spaceone.dashboard.model import PrivateDashboard, PrivateDashboardVersion +from spaceone.dashboard.error import * + +_LOGGER = logging.getLogger(__name__) + + +@authentication_handler +@authorization_handler +@mutation_handler +@event_handler +class PrivateDashboardService(BaseService): + resource = "PrivateDashboard" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.dashboard_mgr: PrivateDashboardManager = self.locator.get_manager( + "PrivateDashboardManager" + ) + self.version_mgr: PrivateDashboardVersionManager = self.locator.get_manager( + "PrivateDashboardVersionManager" + ) + self.identity_mgr: IdentityManager = self.locator.get_manager("IdentityManager") + + @transaction(permission="dashboard:PrivateDashboard.write", role_types=["USER"]) + @check_required(["name", "domain_id", "user_id"]) + def create(self, params: dict) -> PrivateDashboard: + """Register private_dashboard + + Args: + params (dict): { + 'name': 'str', # required + 'layouts': 'list', + 'variables': 'dict', + 'settings': 'dict', + 'variables_schema': 'dict', + 'labels': 'list', + 'tags': 'dict', + 'domain_id': 'str', # injected from auth (required) + 'user_id': 'str' # injected from auth (required) + } + + Returns: + private_dashboard_vo (object) + """ + + dashboard_vo = self.dashboard_mgr.create_private_dashboard(params) + + version_keys = ["layouts", "variables", "variables_schema"] + if any(set(version_keys) & set(params.keys())): + self.version_mgr.create_version_by_private_dashboard_vo( + dashboard_vo, params + ) + + return dashboard_vo + + @transaction(permission="dashboard:PrivateDashboard.write", role_types=["USER"]) + @check_required(["private_dashboard_id", "domain_id", "user_id"]) + def update(self, params): + """Update private_dashboard + + Args: + params (dict): { + 'private_dashboard_id': 'str', # required + 'name': 'str', + 'layouts': 'list', + 'variables': 'dict', + 'settings': 'dict', + 'variables_schema': 'list', + 'labels': 'list', + 'tags': 'dict', + 'domain_id': 'str' # injected from auth (required) + 'user_id': 'str' # injected from auth (required) + } + + Returns: + private_dashboard_vo (object) + """ + + private_dashboard_id = params["private_dashboard_id"] + domain_id = params["domain_id"] + + dashboard_vo: PrivateDashboard = self.dashboard_mgr.get_private_dashboard( + private_dashboard_id, domain_id + ) + + if "name" not in params: + params["name"] = dashboard_vo.name + + if "settings" in params: + params["settings"] = self._merge_settings( + dashboard_vo.settings, params["settings"] + ) + + version_change_keys = ["layouts", "variables", "variables_schema"] + if self._has_version_key_in_params(dashboard_vo, params, version_change_keys): + self.dashboard_mgr.increase_version(dashboard_vo) + self.version_mgr.create_version_by_private_dashboard_vo( + dashboard_vo, params + ) + + return self.dashboard_mgr.update_private_dashboard_by_vo(params, dashboard_vo) + + @transaction(permission="dashboard:PrivateDashboard.write", role_types=["USER"]) + @check_required(["private_dashboard_id", "domain_id", "user_id"]) + def delete(self, params): + """Deregister private_dashboard + + Args: + params (dict): { + 'private_dashboard_id': 'str', # required + 'domain_id': 'str' # injected from auth (required) + 'user_id': 'str' # injected from auth (required) + } + + Returns: + None + """ + private_dashboard_id = params["private_dashboard_id"] + domain_id = params["domain_id"] + + dashboard_vo: PrivateDashboard = self.dashboard_mgr.get_private_dashboard( + private_dashboard_id, domain_id + ) + + if private_dashboard_version_vos := self.version_mgr.filter_versions( + private_dashboard_id=dashboard_vo.private_dashboard_id, domain_id=domain_id + ): + self.version_mgr.delete_versions_by_private_dashboard_version_vos( + private_dashboard_version_vos + ) + + self.dashboard_mgr.delete_by_private_dashboard_vo(dashboard_vo) + + @transaction(permission="dashboard:PrivateDashboard.read", role_types=["USER"]) + @check_required(["private_dashboard_id", "domain_id", "user_id"]) + def get(self, params): + """Get private_dashboard + + Args: + params (dict): { + 'private_dashboard_id': 'str', # required + 'domain_id': 'str' # injected from auth (required) + 'user_id': 'str' # injected from auth (required) + } + + Returns: + private_dashboard_vo (object) + """ + private_dashboard_id = params["private_dashboard_id"] + domain_id = params["domain_id"] + + dashboard_vo = self.dashboard_mgr.get_private_dashboard( + private_dashboard_id, domain_id + ) + + return dashboard_vo + + @transaction(permission="dashboard:PrivateDashboard.write", role_types=["USER"]) + @check_required(["private_dashboard_id", "version", "domain_id", "user_id"]) + def delete_version(self, params): + """delete version of domain dashboard + + Args: + params (dict): { + 'private_dashboard_id': 'str', # required + 'version': 'int', # required + 'domain_id': 'str' # injected from auth (required) + 'user_id': 'str' # injected from auth (required) + } + + Returns: + None + """ + + private_dashboard_id = params["private_dashboard_id"] + version = params["version"] + domain_id = params["domain_id"] + + dashboard_vo = self.dashboard_mgr.get_private_dashboard( + private_dashboard_id, domain_id + ) + + current_version = dashboard_vo.version + if current_version == version: + raise ERROR_LATEST_VERSION(version=version) + + self.version_mgr.delete_version(private_dashboard_id, version, domain_id) + + @transaction(permission="dashboard:PrivateDashboard.write", role_types=["USER"]) + @check_required(["private_dashboard_id", "version", "domain_id", "user_id"]) + def revert_version(self, params): + """Revert version of domain dashboard + + Args: + params (dict): { + 'private_dashboard_id': 'str', # required + 'version': 'int', # required + 'domain_id': 'str' # injected from auth (required) + 'user_id': 'str' # injected from auth (required) + } + + Returns: + private_dashboard_vo (object) + """ + + private_dashboard_id = params["private_dashboard_id"] + version = params["version"] + domain_id = params["domain_id"] + + dashboard_vo: PrivateDashboard = self.dashboard_mgr.get_private_dashboard( + private_dashboard_id, domain_id + ) + + version_vo: PrivateDashboardVersion = self.version_mgr.get_version( + private_dashboard_id, version, domain_id + ) + + params["layouts"] = version_vo.layouts + params["variables"] = version_vo.variables + params["variables_schema"] = version_vo.variables_schema + + self.dashboard_mgr.increase_version(dashboard_vo) + self.version_mgr.create_version_by_private_dashboard_vo(dashboard_vo, params) + + return self.dashboard_mgr.update_private_dashboard_by_vo(params, dashboard_vo) + + @transaction(permission="dashboard:PrivateDashboard.read", role_types=["USER"]) + @check_required(["private_dashboard_id", "version", "domain_id", "user_id"]) + def get_version(self, params): + """Get version of domain dashboard + + Args: + params (dict): { + 'private_dashboard_id': 'str', # required + 'version': 'int', # required + 'domain_id': 'str' # injected from auth (required) + 'user_id': 'str' # injected from auth (required) + } + + Returns: + private_dashboard_version_vo (object) + """ + + private_dashboard_id = params["private_dashboard_id"] + version = params["version"] + domain_id = params["domain_id"] + + return self.version_mgr.get_version(private_dashboard_id, version, domain_id) + + @transaction(permission="dashboard:PrivateDashboard.read", role_types=["USER"]) + @check_required(["private_dashboard_id", "domain_id", "user_id"]) + @append_query_filter(["private_dashboard_id", "version", "domain_id", "user_id"]) + @append_keyword_filter(["private_dashboard_id", "version"]) + def list_versions(self, params): + """List versions of domain dashboard + + Args: + params (dict): { + 'private_dashboard_id': 'str', # required + 'query': 'dict (spaceone.api.core.v1.Query)' + 'version': 'int', + 'domain_id': 'str' # injected from auth (required) + 'user_id': 'str' # injected from auth (required) + } + + Returns: + private_dashboard_version_vos (object) + total_count + """ + private_dashboard_id = params["private_dashboard_id"] + domain_id = params["domain_id"] + + query = params.get("query", {}) + private_dashboard_version_vos, total_count = self.version_mgr.list_versions( + query + ) + dashboard_vo = self.dashboard_mgr.get_private_dashboard( + private_dashboard_id, domain_id + ) + + return private_dashboard_version_vos, total_count, dashboard_vo.version + + @transaction(permission="dashboard:PrivateDashboard.read", role_types=["USER"]) + @check_required(["domain_id"]) + @append_query_filter(["private_dashboard_id", "name", "domain_id", "user_id"]) + @append_keyword_filter(["private_dashboard_id", "name"]) + def list(self, params): + """List private_dashboards + + Args: + params (dict): { + 'query': 'dict (spaceone.api.core.v1.Query)' + 'private_dashboard_id': 'str', + 'name': 'str', + 'domain_id': 'str', # injected from auth (required) + 'user_id': 'str' # injected from auth (required) + } + + Returns: + private_dashboard_vos (object) + total_count + """ + + query = params.get("query", {}) + + return self.dashboard_mgr.list_private_dashboards(query) + + @transaction(permission="dashboard:PrivateDashboard.read", role_types=["USER"]) + @check_required(["query", "domain_id"]) + @append_query_filter(["domain_id", "user_id"]) + @append_keyword_filter(["private_dashboard_id"]) + def stat(self, params): + """ + Args: + params (dict): { + 'query': 'dict (spaceone.api.core.v1.StatisticsQuery)' + 'domain_id': 'str' # injected from auth (required) + 'user_id': 'str' # injected from auth (required) + } + + Returns: + values (list) : 'list of statistics data' + + """ + + query = params.get("query", {}) + + return self.dashboard_mgr.stat_private_dashboards(query) + + @staticmethod + def _has_version_key_in_params( + dashboard_vo: PrivateDashboard, params: dict, version_change_keys: list + ) -> bool: + layouts = dashboard_vo.layouts + variables = dashboard_vo.variables + variables_schema = dashboard_vo.variables_schema + + if any(key for key in params if key in version_change_keys): + if layouts_from_params := params.get("layouts"): + if layouts != layouts_from_params: + return True + if options_from_params := params.get("variables"): + if variables != options_from_params: + return True + if schema_from_params := params.get("variables_schema"): + if schema_from_params != variables_schema: + return True + return False + + @staticmethod + def _merge_settings(old_settings: dict, new_settings: dict) -> dict: + settings = copy.deepcopy(old_settings) + + if old_settings: + settings.update(new_settings) + return settings + else: + return new_settings diff --git a/src/spaceone/dashboard/service/public_dashboard_service.py b/src/spaceone/dashboard/service/public_dashboard_service.py index 5b0f86a..e7408d1 100644 --- a/src/spaceone/dashboard/service/public_dashboard_service.py +++ b/src/spaceone/dashboard/service/public_dashboard_service.py @@ -34,9 +34,9 @@ def __init__(self, *args, **kwargs): permission="dashboard:PublicDashboard.write", role_types=["DOMAIN_ADMIN", "WORKSPACE_OWNER", "WORKSPACE_MEMBER"], ) - @check_required(["name", "dashboard_type", "domain_id"]) + @check_required(["name", "domain_id"]) def create(self, params: dict) -> PublicDashboard: - """Register domain_dashboard + """Register public_dashboard Args: params (dict): { @@ -55,7 +55,7 @@ def create(self, params: dict) -> PublicDashboard: } Returns: - dashboard_vo (object) + public_dashboard_vo (object) """ resource_group = params["resource_group"] @@ -89,7 +89,7 @@ def create(self, params: dict) -> PublicDashboard: ) @check_required(["public_dashboard_id", "domain_id"]) def update(self, params): - """Update domain_dashboard + """Update public_dashboard Args: params (dict): { @@ -107,7 +107,7 @@ def update(self, params): } Returns: - dashboard_vo (object) + public_dashboard_vo (object) """ public_dashboard_id = params["public_dashboard_id"] @@ -140,7 +140,7 @@ def update(self, params): ) @check_required(["public_dashboard_id", "domain_id"]) def delete(self, params): - """Deregister domain_dashboard + """Deregister public_dashboard Args: params (dict): { @@ -162,11 +162,11 @@ def delete(self, params): public_dashboard_id, domain_id, workspace_id, user_projects ) - if domain_dashboard_version_vos := self.version_mgr.filter_versions( + if public_dashboard_version_vos := self.version_mgr.filter_versions( public_dashboard_id=dashboard_vo.public_dashboard_id, domain_id=domain_id ): self.version_mgr.delete_versions_by_public_dashboard_version_vos( - domain_dashboard_version_vos + public_dashboard_version_vos ) self.dashboard_mgr.delete_by_public_dashboard_vo(dashboard_vo) @@ -179,7 +179,7 @@ def delete(self, params): @change_value_by_rule("APPEND", "user_projects", "*") @check_required(["public_dashboard_id", "domain_id"]) def get(self, params): - """Get domain_dashboard + """Get public_dashboard Args: params (dict): { @@ -190,7 +190,7 @@ def get(self, params): } Returns: - dashboard_vo (object) + public_dashboard_vo (object) """ public_dashboard_id = params["public_dashboard_id"] domain_id = params["domain_id"] @@ -258,7 +258,7 @@ def revert_version(self, params): } Returns: - dashboard_vo (object) + public_dashboard_vo (object) """ public_dashboard_id = params["public_dashboard_id"] @@ -304,7 +304,7 @@ def get_version(self, params): } Returns: - domain_dashboard_version_vo (object) + public_dashboard_version_vo (object) """ public_dashboard_id = params["public_dashboard_id"] @@ -336,7 +336,7 @@ def list_versions(self, params): } Returns: - domain_dashboard_version_vos (object) + public_dashboard_version_vos (object) total_count """ public_dashboard_id = params["public_dashboard_id"] @@ -345,14 +345,14 @@ def list_versions(self, params): user_projects = params.get("user_projects") query = params.get("query", {}) - domain_dashboard_version_vos, total_count = self.version_mgr.list_versions( + public_dashboard_version_vos, total_count = self.version_mgr.list_versions( query ) dashboard_vo = self.dashboard_mgr.get_public_dashboard( public_dashboard_id, domain_id, workspace_id, user_projects ) - return domain_dashboard_version_vos, total_count, dashboard_vo.version + return public_dashboard_version_vos, total_count, dashboard_vo.version @transaction( permission="dashboard:PublicDashboard.read", @@ -361,7 +361,7 @@ def list_versions(self, params): @change_value_by_rule("APPEND", "workspace_id", "*") @change_value_by_rule("APPEND", "user_projects", "*") @check_required(["domain_id"]) - @append_query_filter(["public_dashboard_id", "name", "viewers", "domain_id"]) + @append_query_filter(["public_dashboard_id", "name", "domain_id"]) @append_keyword_filter(["public_dashboard_id", "name"]) def list(self, params): """List public_dashboards @@ -378,7 +378,7 @@ def list(self, params): } Returns: - domain_dashboard_vos (object) + public_dashboard_vos (object) total_count """