From 943ab4e032ee902fd77e51e070a7dc19ab782775 Mon Sep 17 00:00:00 2001 From: secloud <47274844+iSecloud@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:52:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20gen=5Fperms=5Fapply=5Fdata=E6=8B=93?= =?UTF-8?q?=E6=89=91=E8=B5=84=E6=BA=90=E6=8C=89=E7=85=A7=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E8=81=9A=E5=90=88=20(#90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Reviewed, transaction id: 6369 --- iam/__version__.py | 2 +- iam/utils.py | 101 +++++++++++++++++++++++--------------------- readme.md | 2 +- readme_en.md | 2 +- release.md | 5 +++ tests/test_utils.py | 70 +++++++++++++++++++++--------- 6 files changed, 113 insertions(+), 69 deletions(-) diff --git a/iam/__version__.py b/iam/__version__.py index fdc6eda..918e7a1 100644 --- a/iam/__version__.py +++ b/iam/__version__.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- -__version__ = "1.3.5" +__version__ = "1.3.6" diff --git a/iam/utils.py b/iam/utils.py index 7eab38f..10994ad 100644 --- a/iam/utils.py +++ b/iam/utils.py @@ -9,9 +9,8 @@ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ - - -from collections import OrderedDict +import itertools +from collections import OrderedDict, defaultdict from . import meta @@ -61,51 +60,60 @@ def gen_perms_apply_data(system, subject, action_to_resources_list): for system_id, resources in system_resources.items(): system_resources_list.setdefault(system_id, []).append(resources) + # 2. aggregate resources by resource type, generate related_resource_type related_resource_types = [] for system_id, resources_list in system_resources_list.items(): - # get resource type from last resource in resources - a_resource = resources_list[0][-1] - resource_types = { - "system_id": system_id, - "system_name": meta.get_system_name(system_id), - "type": a_resource.type, - "type_name": meta.get_resource_name(system_id, a_resource.type), - } - instances = [] - - for resources in resources_list: + if not resources_list: + continue + + # aggregate resources by resource type + resource_type__resources = defaultdict(list) + for resource in list(itertools.chain(*resources_list)): + resource_type__resources[resource.type].append(resource) + + # get the list of resource instances of the same type + for __, resources in resource_type__resources.items(): + a_resource = resources[0] + resource_types = { + "system_id": system_id, + "system_name": meta.get_system_name(system_id), + "type": a_resource.type, + "type_name": meta.get_resource_name(system_id, a_resource.type), + } + instances = [] + + # arrange instances according to topo level for resource in resources: inst_item = [] - topo_path = None - - if resource.attribute: - topo_path = resource.attribute.get("_bk_iam_path_") - - if topo_path: - for part in topo_path[1:-1].split("/"): - # NOTE: old _bk_iam_path_ is like /set,1/host,2/ - # while the new _bk_iam_path_ is like /bk_cmdb,set,1/bk_cmdb,host,2/ - node_parts = part.split(",") - # NOTE: topo resources should be considered to belong to different systems - rsystem, rtype, rid = system_id, "", "" - if len(node_parts) == 2: - rtype, rid = node_parts[0], node_parts[1] - elif len(node_parts) == 3: - rsystem, rtype, rid = node_parts[0], node_parts[1], node_parts[2] - # NOTE: currently, keep the name of /bk_cmdb,set,1/ same as /set,1/ - part = ",".join(node_parts[1:]) - else: - raise Exception("Invalid _bk_iam_path_: %s" % topo_path) - - inst_item.append( - { - "type": rtype, - "type_name": meta.get_resource_name(rsystem, rtype), - "id": rid, - "name": part, - } - ) - + topo_path = [] + # get the topo level of the resource + if resource.attribute and resource.attribute.get("_bk_iam_path_"): + bk_iam_path = resource.attribute["_bk_iam_path_"] + topo_path = bk_iam_path[1:-1].split("/") + # append paernt topo instance + for part in topo_path: + # NOTE: old _bk_iam_path_ is like /set,1/host,2/ + # while the new _bk_iam_path_ is like /bk_cmdb,set,1/bk_cmdb,host,2/ + node_parts = part.split(",") + # NOTE: topo resources should be considered to belong to different systems + rsystem, rtype, rid = system_id, "", "" + if len(node_parts) == 2: + rtype, rid = node_parts[0], node_parts[1] + elif len(node_parts) == 3: + rsystem, rtype, rid = node_parts[0], node_parts[1], node_parts[2] + # NOTE: currently, keep the name of /bk_cmdb,set,1/ same as /set,1/ + part = ",".join(node_parts[1:]) + else: + raise Exception("Invalid _bk_iam_path_: %s" % topo_path) + inst_item.append( + { + "type": rtype, + "type_name": meta.get_resource_name(rsystem, rtype), + "id": rid, + "name": part, + } + ) + # lastly, append self inst_item.append( { "type": resource.type, @@ -114,11 +122,10 @@ def gen_perms_apply_data(system, subject, action_to_resources_list): "name": resource.attribute.get("name", "") if resource.attribute else "", } ) - instances.append(inst_item) - resource_types["instances"] = instances - related_resource_types.append(resource_types) + resource_types["instances"] = instances + related_resource_types.append(resource_types) action["related_resource_types"] = related_resource_types actions.append(action) diff --git a/readme.md b/readme.md index 454ab2c..8e499c0 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@ ![](docs/resource/img/bk_iam_zh.png) --- -[![license](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/TencentBlueKing/iam-python-sdk/blob/master/LICENSE.txt) [![Release Version](https://img.shields.io/badge/release-1.3.5-brightgreen.svg)](https://github.com/TencentBlueKing/iam-python-sdk/releases) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/TencentBlueKing/iam-python-sdk/pulls) [![BK Pipelines Status](https://api.bkdevops.qq.com/process/api/external/pipelines/projects/iam/p-5c359e750bb9457984ab84656651d843/badge?X-DEVOPS-PROJECT-ID=iam)](http://devops.oa.com/process/api-html/user/builds/projects/iam/pipelines/p-5c359e750bb9457984ab84656651d843/latestFinished?X-DEVOPS-PROJECT-ID=iam) +[![license](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/TencentBlueKing/iam-python-sdk/blob/master/LICENSE.txt) [![Release Version](https://img.shields.io/badge/release-1.3.6-brightgreen.svg)](https://github.com/TencentBlueKing/iam-python-sdk/releases) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/TencentBlueKing/iam-python-sdk/pulls) [![BK Pipelines Status](https://api.bkdevops.qq.com/process/api/external/pipelines/projects/iam/p-5c359e750bb9457984ab84656651d843/badge?X-DEVOPS-PROJECT-ID=iam)](http://devops.oa.com/process/api-html/user/builds/projects/iam/pipelines/p-5c359e750bb9457984ab84656651d843/latestFinished?X-DEVOPS-PROJECT-ID=iam) [(English Documents Available)](readme_en.md) diff --git a/readme_en.md b/readme_en.md index 2319785..fb90b48 100644 --- a/readme_en.md +++ b/readme_en.md @@ -1,7 +1,7 @@ ![](docs/resource/img/bk_iam_en.png) --- -[![license](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/TencentBlueKing/iam-python-sdk/blob/master/LICENSE.txt) [![Release Version](https://img.shields.io/badge/release-1.3.5-brightgreen.svg)](https://github.com/TencentBlueKing/iam-python-sdk/releases) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/TencentBlueKing/iam-python-sdk/pulls) [![BK Pipelines Status](https://api.bkdevops.qq.com/process/api/external/pipelines/projects/iam/p-5c359e750bb9457984ab84656651d843/badge?X-DEVOPS-PROJECT-ID=iam)](http://devops.oa.com/process/api-html/user/builds/projects/iam/pipelines/p-5c359e750bb9457984ab84656651d843/latestFinished?X-DEVOPS-PROJECT-ID=iam) +[![license](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/TencentBlueKing/iam-python-sdk/blob/master/LICENSE.txt) [![Release Version](https://img.shields.io/badge/release-1.3.6-brightgreen.svg)](https://github.com/TencentBlueKing/iam-python-sdk/releases) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/TencentBlueKing/iam-python-sdk/pulls) [![BK Pipelines Status](https://api.bkdevops.qq.com/process/api/external/pipelines/projects/iam/p-5c359e750bb9457984ab84656651d843/badge?X-DEVOPS-PROJECT-ID=iam)](http://devops.oa.com/process/api-html/user/builds/projects/iam/pipelines/p-5c359e750bb9457984ab84656651d843/latestFinished?X-DEVOPS-PROJECT-ID=iam) ## Overview diff --git a/release.md b/release.md index bc1dda4..bcf8d43 100644 --- a/release.md +++ b/release.md @@ -1,6 +1,11 @@ 版本日志 =============== +# v1.3.5 + +- fix: gen_perms_apply_data拓扑资源按照资源类型聚合 + + # v1.3.5 - add: list_instance、search_instance 新增 ancestors 返回 diff --git a/tests/test_utils.py b/tests/test_utils.py index bea28de..6a5eb4d 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -90,7 +90,7 @@ def get_resource_name(system, resource): ], ) - # assert data + # assert data assert data == { "system_id": "test_system", "system_name": "test_system_name", @@ -102,8 +102,8 @@ def get_resource_name(system, resource): { "system_id": "test_system", "system_name": "test_system_name", - "type": "r3", - "type_name": "r3_type", + "type": "r1", + "type_name": "r1_type", "instances": [ [ { @@ -112,7 +112,15 @@ def get_resource_name(system, resource): "id": "r1id", "name": "r1n" } - ], + ] + ] + }, + { + "system_id": "test_system", + "system_name": "test_system_name", + "type": "r2", + "type_name": "r2_type", + "instances": [ [ { "type": "r2", @@ -120,7 +128,15 @@ def get_resource_name(system, resource): "id": "r2id", "name": "" } - ], + ] + ] + }, + { + "system_id": "test_system", + "system_name": "test_system_name", + "type": "r3", + "type_name": "r3_type", + "instances": [ [ { "type": "r3", @@ -161,8 +177,8 @@ def get_resource_name(system, resource): { "system_id": "test_system", "system_name": "test_system_name", - "type": "r3", - "type_name": "r3_type", + "type": "r1", + "type_name": "r1_type", "instances": [ [ { @@ -172,14 +188,6 @@ def get_resource_name(system, resource): "name": "r1n" } ], - [ - { - "type": "r3", - "type_name": "r3_type", - "id": "r3id", - "name": "" - } - ], [ { "type": "r1", @@ -187,7 +195,15 @@ def get_resource_name(system, resource): "id": "r1id", "name": "r1n" } - ], + ] + ] + }, + { + "system_id": "test_system", + "system_name": "test_system_name", + "type": "r3", + "type_name": "r3_type", + "instances": [ [ { "type": "r3", @@ -198,9 +214,9 @@ def get_resource_name(system, resource): ], [ { - "type": "r2", - "type_name": "r2_type", - "id": "r2id", + "type": "r3", + "type_name": "r3_type", + "id": "r3id", "name": "" } ], @@ -214,6 +230,22 @@ def get_resource_name(system, resource): ] ] }, + { + "system_id": "test_system", + "system_name": "test_system_name", + "type": "r2", + "type_name": "r2_type", + "instances": [ + [ + { + "type": "r2", + "type_name": "r2_type", + "id": "r2id", + "name": "" + } + ] + ] + }, { "system_id": "another_system", "system_name": "another_system_name",