diff --git a/src/cloudforet/search/conf/search_conf.py b/src/cloudforet/search/conf/search_conf.py index 95a77ed..5d4fe24 100644 --- a/src/cloudforet/search/conf/search_conf.py +++ b/src/cloudforet/search/conf/search_conf.py @@ -1,3 +1,5 @@ +# aliases are convert 'key' to 'value' name +# tags are store 'key' at tags with result['value'] RESOURCE_TYPES = { "identity.ServiceAccount": { "request": { @@ -7,17 +9,38 @@ "data.subscription_id", "data.tenant_id", "data.project_id", - ] + ], + "projection": { + "name": 1, + "data": 1, + "service_account_id": 1, + "domain_id": 1, + "workspace_id": 1, + "project_id": 1, + "account": { + "$switch": { + "branches": [ + { + "case": {"$ifNull": ["$data.account_id", None]}, + "then": "$data.account_id", + }, + { + "case": {"$ifNull": ["$data.subscription_id", None]}, + "then": "$data.subscription_id", + }, + { + "case": {"$ifNull": ["$data.project_id", None]}, + "then": "$data.project_id", + }, + ], + "default": "$service_account_id", + } + }, + }, }, "response": { "resource_id": "service_account_id", - "name": "{account} ({name})", - "aliases": [ - {"data.account_id": "account"}, - {"data.subscription_id": "account"}, - {"data.project_id": "account"}, - {"service_account_id": "account"}, - ], + "name": "{name} ({account})", }, }, "identity.Project": { @@ -29,18 +52,26 @@ "response": {"resource_id": "workspace_id", "name": "{name}"}, }, "inventory.CloudServiceType": { - "request": {"search": ["name", "group", "provider"]}, + "request": { + "search": ["name", "group", "provider"], + "projection": { + "group": 1, + "name": 1, + "provider": 1, + "cloud_service_type_id": 1, + "workspace_id": 1, + "domain_id": 1, + "icon": "$tags.spaceone:icon", + }, + }, "response": { "resource_id": "cloud_service_type_id", "name": "{group} > {name}", - "aliases": [ - {"tags.spaceone:icon": "icon"}, - ], "tags": { - "provider": "{provider}", - "icon": "{icon}", - "group": "{group}", - "name": "{name}", + "provider": "provider", + "icon": "icon", + "group": "group", + "name": "name", }, }, }, @@ -48,11 +79,46 @@ "request": { "search": ["name", "ip_addresses", "account"], "filter": [{"state": "ACTIVE"}], + "projection": { + "cloud_service_id": 1, + "cloud_service_type": 1, + "cloud_service_group": 1, + "name": 1, + "provider": 1, + "ip_addresses": { + "$reduce": { + "input": "$ip_addresses", + "initialValue": "", + "in": {"$concat": ["$$value", "$$this", ","]}, + } + }, + "project_id": 1, + "workspace_id": 1, + "domain_id": 1, + "ref_resource_id": "$reference.resource_id", + "cloud_service_type_key": { + "$concat": [ + "$provider", + ":", + "$cloud_service_type", + ":", + "$cloud_service_group", + ] + }, + }, }, "response": { "resource_id": "cloud_service_id", - "name": "{name}", + "name": "{name}({ip_addresses})({ref_resource_id})", "description": "{cloud_service_group} > {cloud_service_type}", + "tags": { + "cloud_service_type_key": "cloud_service_type_key", + "ip_addresses": "ip_addresses", + "provider": "provider", + "group": "cloud_service_group", + "name": "cloud_service_type", + "resource_id": "resource_id", + }, }, }, "dashboard.PublicDashboard": { diff --git a/src/cloudforet/search/lib/utils.py b/src/cloudforet/search/lib/utils.py new file mode 100644 index 0000000..3c47ff9 --- /dev/null +++ b/src/cloudforet/search/lib/utils.py @@ -0,0 +1,22 @@ +def save_to_dict_value( + data: dict, + dotted_key: str, + value: any, + default_value: any = None, + overwrite: bool = False, +) -> dict: + if "." in dotted_key: + key, rest_dotted_key = dotted_key.split(".", 1) + print("key, rest_dotted_key", key, rest_dotted_key) + if key not in data: + data[key] = {} + + if len(rest_dotted_key) > 0: + print("nested") + save_to_dict_value(data[key], rest_dotted_key, value, default_value) + else: + if dotted_key not in data or overwrite is True: + data[dotted_key] = value + print("not dotted", data, dotted_key, value) + + return data diff --git a/src/cloudforet/search/manager/resource_manager.py b/src/cloudforet/search/manager/resource_manager.py index 972b9a0..0be52f7 100644 --- a/src/cloudforet/search/manager/resource_manager.py +++ b/src/cloudforet/search/manager/resource_manager.py @@ -21,6 +21,7 @@ def search_resource( self, domain_id: str, find_filter: dict, + projection: dict, resource_type: str, limit: int, page: int, @@ -30,7 +31,7 @@ def search_resource( results = list( self.client[db_name][collection_name].find( - filter=find_filter, limit=limit, skip=skip_count + filter=find_filter, projection=projection, limit=limit, skip=skip_count ) ) diff --git a/src/cloudforet/search/service/resource.py b/src/cloudforet/search/service/resource.py index 4fd89f9..1b5ba67 100644 --- a/src/cloudforet/search/service/resource.py +++ b/src/cloudforet/search/service/resource.py @@ -8,6 +8,7 @@ from spaceone.core.service.utils import * from spaceone.core.utils import * +from cloudforet.search.lib.utils import * from cloudforet.search.manager.resource_manager import ResourceManager from cloudforet.search.manager.identity_manager import IdentityManager from cloudforet.search.model.resource.response import * @@ -146,8 +147,9 @@ def search(self, params: ResourceSearchRequest) -> Union[ResourcesResponse, dict ) # search resources + projection = self.search_conf[resource_type]["request"].get("projection", {}) results = self.resource_manager.search_resource( - domain_id, find_filter, resource_type, limit, page + domain_id, find_filter, projection, resource_type, limit, page ) next_token = self._encode_next_token_base64( @@ -280,8 +282,6 @@ def _make_response( # Make description at response if description_format: result["description"] = description_format.format(**result) - if aliases: - result = self._convert_result_by_alias(result, aliases) if tags: result = self._add_additional_info_to_tags(result, tags) else: @@ -400,14 +400,15 @@ def _convert_result_by_alias(result: dict, aliases: list) -> dict: for target_field, alias_name in alias.items(): if value := get_dict_value(result, target_field): if not result.get(alias_name): - result[alias_name] = value + result[alias_name] = value.format(**result) + # result = save_to_dict_value(result, alias_name, value) return result @staticmethod def _add_additional_info_to_tags(result: dict, tags: dict) -> dict: response_tags = {} for key, value in tags.items(): - if target_value := get_dict_value(result, key): + if target_value := get_dict_value(result, value): response_tags[key] = target_value result["tags"] = response_tags return result