99an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
1010specific language governing permissions and limitations under the License.
1111"""
12-
13-
14- from collections import OrderedDict
12+ import itertools
13+ from collections import OrderedDict , defaultdict
1514
1615from . import meta
1716
@@ -61,51 +60,60 @@ def gen_perms_apply_data(system, subject, action_to_resources_list):
6160 for system_id , resources in system_resources .items ():
6261 system_resources_list .setdefault (system_id , []).append (resources )
6362
63+ # 2. aggregate resources by resource type, generate related_resource_type
6464 related_resource_types = []
6565 for system_id , resources_list in system_resources_list .items ():
66- # get resource type from last resource in resources
67- a_resource = resources_list [0 ][- 1 ]
68- resource_types = {
69- "system_id" : system_id ,
70- "system_name" : meta .get_system_name (system_id ),
71- "type" : a_resource .type ,
72- "type_name" : meta .get_resource_name (system_id , a_resource .type ),
73- }
74- instances = []
75-
76- for resources in resources_list :
66+ if not resources_list :
67+ continue
68+
69+ # aggregate resources by resource type
70+ resource_type__resources = defaultdict (list )
71+ for resource in list (itertools .chain (* resources_list )):
72+ resource_type__resources [resource .type ].append (resource )
73+
74+ # get the list of resource instances of the same type
75+ for __ , resources in resource_type__resources .items ():
76+ a_resource = resources [0 ]
77+ resource_types = {
78+ "system_id" : system_id ,
79+ "system_name" : meta .get_system_name (system_id ),
80+ "type" : a_resource .type ,
81+ "type_name" : meta .get_resource_name (system_id , a_resource .type ),
82+ }
83+ instances = []
84+
85+ # arrange instances according to topo level
7786 for resource in resources :
7887 inst_item = []
79- topo_path = None
80-
81- if resource .attribute :
82- topo_path = resource .attribute .get ("_bk_iam_path_" )
83-
84- if topo_path :
85- for part in topo_path [1 :- 1 ].split ("/" ):
86- # NOTE: old _bk_iam_path_ is like /set,1/host,2/
87- # while the new _bk_iam_path_ is like /bk_cmdb,set,1/bk_cmdb,host,2/
88- node_parts = part .split ("," )
89- # NOTE: topo resources should be considered to belong to different systems
90- rsystem , rtype , rid = system_id , "" , ""
91- if len (node_parts ) == 2 :
92- rtype , rid = node_parts [0 ], node_parts [1 ]
93- elif len (node_parts ) == 3 :
94- rsystem , rtype , rid = node_parts [0 ], node_parts [1 ], node_parts [2 ]
95- # NOTE: currently, keep the name of /bk_cmdb,set,1/ same as /set,1/
96- part = "," .join (node_parts [1 :])
97- else :
98- raise Exception ("Invalid _bk_iam_path_: %s" % topo_path )
99-
100- inst_item .append (
101- {
102- "type" : rtype ,
103- "type_name" : meta .get_resource_name (rsystem , rtype ),
104- "id" : rid ,
105- "name" : part ,
106- }
107- )
108-
88+ topo_path = []
89+ # get the topo level of the resource
90+ if resource .attribute and resource .attribute .get ("_bk_iam_path_" ):
91+ bk_iam_path = resource .attribute ["_bk_iam_path_" ]
92+ topo_path = bk_iam_path [1 :- 1 ].split ("/" )
93+ # append paernt topo instance
94+ for part in topo_path :
95+ # NOTE: old _bk_iam_path_ is like /set,1/host,2/
96+ # while the new _bk_iam_path_ is like /bk_cmdb,set,1/bk_cmdb,host,2/
97+ node_parts = part .split ("," )
98+ # NOTE: topo resources should be considered to belong to different systems
99+ rsystem , rtype , rid = system_id , "" , ""
100+ if len (node_parts ) == 2 :
101+ rtype , rid = node_parts [0 ], node_parts [1 ]
102+ elif len (node_parts ) == 3 :
103+ rsystem , rtype , rid = node_parts [0 ], node_parts [1 ], node_parts [2 ]
104+ # NOTE: currently, keep the name of /bk_cmdb,set,1/ same as /set,1/
105+ part = "," .join (node_parts [1 :])
106+ else :
107+ raise Exception ("Invalid _bk_iam_path_: %s" % topo_path )
108+ inst_item .append (
109+ {
110+ "type" : rtype ,
111+ "type_name" : meta .get_resource_name (rsystem , rtype ),
112+ "id" : rid ,
113+ "name" : part ,
114+ }
115+ )
116+ # lastly, append self
109117 inst_item .append (
110118 {
111119 "type" : resource .type ,
@@ -114,11 +122,10 @@ def gen_perms_apply_data(system, subject, action_to_resources_list):
114122 "name" : resource .attribute .get ("name" , "" ) if resource .attribute else "" ,
115123 }
116124 )
117-
118125 instances .append (inst_item )
119126
120- resource_types ["instances" ] = instances
121- related_resource_types .append (resource_types )
127+ resource_types ["instances" ] = instances
128+ related_resource_types .append (resource_types )
122129
123130 action ["related_resource_types" ] = related_resource_types
124131 actions .append (action )
0 commit comments