Browse Source

Merge "Fixes bad performance when editing project members"

Jenkins 4 years ago
parent
commit
8c9b86f130

+ 34
- 0
openstack_dashboard/api/keystone.py View File

@@ -457,6 +457,16 @@ def remove_group_user(request, group_id, user_id):
457 457
     return manager.remove_from_group(group=group_id, user=user_id)
458 458
 
459 459
 
460
+def role_assignments_list(request, project=None, user=None, role=None,
461
+                          group=None, domain=None, effective=False):
462
+    if VERSIONS.active < 3:
463
+        raise exceptions.NotAvailable
464
+
465
+    manager = keystoneclient(request, admin=True).role_assignments
466
+    return manager.list(project=project, user=user, role=role, group=group,
467
+                        domain=domain, effective=effective)
468
+
469
+
460 470
 def role_create(request, name):
461 471
     manager = keystoneclient(request, admin=True).roles
462 472
     return manager.create(name)
@@ -490,6 +500,30 @@ def roles_for_user(request, user, project):
490 500
         return manager.list(user=user, project=project)
491 501
 
492 502
 
503
+def get_project_users_roles(request, project):
504
+    users_roles = {}
505
+    if VERSIONS.active < 3:
506
+        project_users = user_list(request, project=project)
507
+
508
+        for user in project_users:
509
+            roles = roles_for_user(request, user.id, project)
510
+            roles_ids = [role.id for role in roles]
511
+            users_roles[user.id] = roles_ids
512
+    else:
513
+        project_role_assignments = role_assignments_list(request,
514
+                                                         project=project)
515
+        for role_assignment in project_role_assignments:
516
+            if not hasattr(role_assignment, 'user'):
517
+                continue
518
+            user_id = role_assignment.user['id']
519
+            role_id = role_assignment.role['id']
520
+            if user_id in users_roles:
521
+                users_roles[user_id].append(role_id)
522
+            else:
523
+                users_roles[user_id] = [role_id]
524
+    return users_roles
525
+
526
+
493 527
 def add_tenant_user_role(request, project=None, user=None, role=None,
494 528
                          group=None, domain=None):
495 529
     """Adds a role for a user on a tenant."""

+ 99
- 35
openstack_dashboard/dashboards/admin/projects/tests.py View File

@@ -732,10 +732,13 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
732 732
                                        'user_list',
733 733
                                        'roles_for_group',
734 734
                                        'group_list',
735
-                                       'role_list'),
735
+                                       'role_list',
736
+                                       'role_assignments_list'),
736 737
                         quotas: ('get_tenant_quota_data',
737 738
                                  'get_disabled_quotas')})
738 739
     def test_update_project_get(self):
740
+        keystone_api_version = api.keystone.VERSIONS.active
741
+
739 742
         project = self.tenants.first()
740 743
         quota = self.quotas.first()
741 744
         default_role = self.roles.first()
@@ -744,6 +747,7 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
744 747
         groups = self._get_all_groups(domain_id)
745 748
         roles = self.roles.list()
746 749
         proj_users = self._get_proj_users(project.id)
750
+        role_assignments = self.role_assignments.list()
747 751
 
748 752
         api.keystone.tenant_get(IsA(http.HttpRequest),
749 753
                                 self.tenant.id, admin=True) \
@@ -764,12 +768,20 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
764 768
             .MultipleTimes().AndReturn(roles)
765 769
         api.keystone.group_list(IsA(http.HttpRequest), domain=domain_id) \
766 770
             .AndReturn(groups)
767
-        api.keystone.user_list(IsA(http.HttpRequest),
768
-                               project=self.tenant.id).AndReturn(proj_users)
769
-        for user in proj_users:
770
-            api.keystone.roles_for_user(IsA(http.HttpRequest),
771
-                                        user.id,
772
-                                        self.tenant.id).AndReturn(roles)
771
+
772
+        if keystone_api_version >= 3:
773
+            api.keystone.role_assignments_list(IsA(http.HttpRequest),
774
+                                               project=self.tenant.id) \
775
+               .AndReturn(role_assignments)
776
+        else:
777
+            api.keystone.user_list(IsA(http.HttpRequest),
778
+                                   project=self.tenant.id) \
779
+               .AndReturn(proj_users)
780
+
781
+            for user in proj_users:
782
+                api.keystone.roles_for_user(IsA(http.HttpRequest),
783
+                                            user.id,
784
+                                            self.tenant.id).AndReturn(roles)
773 785
 
774 786
         for group in groups:
775 787
             api.keystone.roles_for_group(IsA(http.HttpRequest),
@@ -814,12 +826,16 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
814 826
                                        'remove_group_role',
815 827
                                        'add_group_role',
816 828
                                        'group_list',
817
-                                       'role_list'),
829
+                                       'role_list',
830
+                                       'role_assignments_list'),
818 831
                         api.nova: ('tenant_quota_update',),
819 832
                         api.cinder: ('tenant_quota_update',),
820 833
                         quotas: ('get_tenant_quota_data',
821 834
                                  'get_disabled_quotas')})
835
+
822 836
     def test_update_project_save(self, neutron=False):
837
+        keystone_api_version = api.keystone.VERSIONS.active
838
+
823 839
         project = self.tenants.first()
824 840
         quota = self.quotas.first()
825 841
         default_role = self.roles.first()
@@ -829,6 +845,7 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
829 845
         groups = self._get_all_groups(domain_id)
830 846
         proj_groups = self._get_proj_groups(project.id)
831 847
         roles = self.roles.list()
848
+        role_assignments = self.role_assignments.list()
832 849
 
833 850
         # get/init
834 851
         api.keystone.tenant_get(IsA(http.HttpRequest),
@@ -853,13 +870,23 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
853 870
             .MultipleTimes().AndReturn(roles)
854 871
         api.keystone.group_list(IsA(http.HttpRequest), domain=domain_id) \
855 872
             .AndReturn(groups)
856
-        api.keystone.user_list(IsA(http.HttpRequest),
857
-                               project=self.tenant.id).AndReturn(proj_users)
873
+
858 874
         workflow_data = {}
859
-        for user in proj_users:
860
-            api.keystone.roles_for_user(IsA(http.HttpRequest),
861
-                                        user.id,
862
-                                        self.tenant.id).AndReturn(roles)
875
+
876
+        if keystone_api_version >= 3:
877
+            api.keystone.role_assignments_list(IsA(http.HttpRequest),
878
+                                               project=self.tenant.id) \
879
+               .AndReturn(role_assignments)
880
+        else:
881
+            api.keystone.user_list(IsA(http.HttpRequest),
882
+                                   project=self.tenant.id) \
883
+               .AndReturn(proj_users)
884
+
885
+            for user in proj_users:
886
+                api.keystone.roles_for_user(IsA(http.HttpRequest),
887
+                                            user.id,
888
+                                            self.tenant.id).AndReturn(roles)
889
+
863 890
         for group in groups:
864 891
             api.keystone.roles_for_group(IsA(http.HttpRequest),
865 892
                                          group=group.id,
@@ -1051,11 +1078,14 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
1051 1078
                                        'remove_group_role',
1052 1079
                                        'add_group_role',
1053 1080
                                        'group_list',
1054
-                                       'role_list'),
1081
+                                       'role_list',
1082
+                                       'role_assignments_list'),
1055 1083
                         quotas: ('get_tenant_quota_data',
1056 1084
                                  'get_disabled_quotas'),
1057 1085
                         api.nova: ('tenant_quota_update',)})
1058 1086
     def test_update_project_tenant_update_error(self):
1087
+        keystone_api_version = api.keystone.VERSIONS.active
1088
+
1059 1089
         project = self.tenants.first()
1060 1090
         quota = self.quotas.first()
1061 1091
         default_role = self.roles.first()
@@ -1064,6 +1094,7 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
1064 1094
         groups = self._get_all_groups(domain_id)
1065 1095
         roles = self.roles.list()
1066 1096
         proj_users = self._get_proj_users(project.id)
1097
+        role_assignments = self.role_assignments.list()
1067 1098
 
1068 1099
         # get/init
1069 1100
         api.keystone.tenant_get(IsA(http.HttpRequest), self.tenant.id,
@@ -1085,15 +1116,24 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
1085 1116
             .MultipleTimes().AndReturn(roles)
1086 1117
         api.keystone.group_list(IsA(http.HttpRequest), domain=domain_id) \
1087 1118
             .AndReturn(groups)
1088
-        api.keystone.user_list(IsA(http.HttpRequest),
1089
-                               project=self.tenant.id).AndReturn(proj_users)
1090 1119
 
1091 1120
         workflow_data = {}
1121
+
1122
+        if keystone_api_version >= 3:
1123
+            api.keystone.role_assignments_list(IsA(http.HttpRequest),
1124
+                                               project=self.tenant.id) \
1125
+               .AndReturn(role_assignments)
1126
+        else:
1127
+            api.keystone.user_list(IsA(http.HttpRequest),
1128
+                                   project=self.tenant.id) \
1129
+               .AndReturn(proj_users)
1130
+            for user in proj_users:
1131
+                api.keystone.roles_for_user(IsA(http.HttpRequest),
1132
+                                            user.id,
1133
+                                            self.tenant.id).AndReturn(roles)
1134
+
1135
+        role_ids = [role.id for role in roles]
1092 1136
         for user in proj_users:
1093
-            api.keystone.roles_for_user(IsA(http.HttpRequest),
1094
-                                        user.id,
1095
-                                        self.tenant.id).AndReturn(roles)
1096
-            role_ids = [role.id for role in roles]
1097 1137
             if role_ids:
1098 1138
                 workflow_data.setdefault(USER_ROLE_PREFIX + role_ids[0], []) \
1099 1139
                              .append(user.id)
@@ -1155,11 +1195,14 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
1155 1195
                                        'remove_group_role',
1156 1196
                                        'add_group_role',
1157 1197
                                        'group_list',
1158
-                                       'role_list'),
1198
+                                       'role_list',
1199
+                                       'role_assignments_list'),
1159 1200
                         quotas: ('get_tenant_quota_data',
1160 1201
                                  'get_disabled_quotas'),
1161 1202
                         api.nova: ('tenant_quota_update',)})
1162 1203
     def test_update_project_quota_update_error(self):
1204
+        keystone_api_version = api.keystone.VERSIONS.active
1205
+
1163 1206
         project = self.tenants.first()
1164 1207
         quota = self.quotas.first()
1165 1208
         default_role = self.roles.first()
@@ -1169,6 +1212,7 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
1169 1212
         groups = self._get_all_groups(domain_id)
1170 1213
         proj_groups = self._get_proj_groups(project.id)
1171 1214
         roles = self.roles.list()
1215
+        role_assignments = self.role_assignments.list()
1172 1216
 
1173 1217
         # get/init
1174 1218
         api.keystone.tenant_get(IsA(http.HttpRequest), self.tenant.id,
@@ -1190,15 +1234,22 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
1190 1234
             .MultipleTimes().AndReturn(roles)
1191 1235
         api.keystone.group_list(IsA(http.HttpRequest), domain=domain_id) \
1192 1236
             .AndReturn(groups)
1193
-        api.keystone.user_list(IsA(http.HttpRequest),
1194
-                       project=self.tenant.id).AndReturn(proj_users)
1195 1237
 
1196 1238
         workflow_data = {}
1197 1239
 
1198
-        for user in proj_users:
1199
-            api.keystone.roles_for_user(IsA(http.HttpRequest),
1200
-                                        user.id,
1201
-                                        self.tenant.id).AndReturn(roles)
1240
+        if keystone_api_version >= 3:
1241
+            api.keystone.role_assignments_list(IsA(http.HttpRequest),
1242
+                                               project=self.tenant.id) \
1243
+               .AndReturn(role_assignments)
1244
+        else:
1245
+            api.keystone.user_list(IsA(http.HttpRequest),
1246
+                                   project=self.tenant.id) \
1247
+               .AndReturn(proj_users)
1248
+
1249
+            for user in proj_users:
1250
+                api.keystone.roles_for_user(IsA(http.HttpRequest),
1251
+                                            user.id,
1252
+                                            self.tenant.id).AndReturn(roles)
1202 1253
 
1203 1254
         for group in groups:
1204 1255
             api.keystone.roles_for_group(IsA(http.HttpRequest),
@@ -1319,10 +1370,13 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
1319 1370
                                        'remove_group_role',
1320 1371
                                        'add_group_role',
1321 1372
                                        'group_list',
1322
-                                       'role_list'),
1373
+                                       'role_list',
1374
+                                       'role_assignments_list'),
1323 1375
                         quotas: ('get_tenant_quota_data',
1324 1376
                                  'get_disabled_quotas')})
1325 1377
     def test_update_project_member_update_error(self):
1378
+        keystone_api_version = api.keystone.VERSIONS.active
1379
+
1326 1380
         project = self.tenants.first()
1327 1381
         quota = self.quotas.first()
1328 1382
         default_role = self.roles.first()
@@ -1331,6 +1385,7 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
1331 1385
         proj_users = self._get_proj_users(project.id)
1332 1386
         groups = self._get_all_groups(domain_id)
1333 1387
         roles = self.roles.list()
1388
+        role_assignments = self.role_assignments.list()
1334 1389
 
1335 1390
         # get/init
1336 1391
         api.keystone.tenant_get(IsA(http.HttpRequest), self.tenant.id,
@@ -1352,14 +1407,23 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
1352 1407
             .MultipleTimes().AndReturn(roles)
1353 1408
         api.keystone.group_list(IsA(http.HttpRequest), domain=domain_id) \
1354 1409
             .AndReturn(groups)
1355
-        api.keystone.user_list(IsA(http.HttpRequest),
1356
-                       project=self.tenant.id).AndReturn(proj_users)
1357 1410
 
1358 1411
         workflow_data = {}
1359
-        for user in proj_users:
1360
-            api.keystone.roles_for_user(IsA(http.HttpRequest),
1361
-                                        user.id,
1362
-                                        self.tenant.id).AndReturn(roles)
1412
+
1413
+        if keystone_api_version >= 3:
1414
+            api.keystone.role_assignments_list(IsA(http.HttpRequest),
1415
+                                               project=self.tenant.id) \
1416
+               .AndReturn(role_assignments)
1417
+        else:
1418
+            api.keystone.user_list(IsA(http.HttpRequest),
1419
+                                   project=self.tenant.id) \
1420
+               .AndReturn(proj_users)
1421
+
1422
+            for user in proj_users:
1423
+                api.keystone.roles_for_user(IsA(http.HttpRequest),
1424
+                                            user.id,
1425
+                                            self.tenant.id).AndReturn(roles)
1426
+
1363 1427
         for group in groups:
1364 1428
             api.keystone.roles_for_group(IsA(http.HttpRequest),
1365 1429
                                          group=group.id,

+ 11
- 16
openstack_dashboard/dashboards/admin/projects/workflows.py View File

@@ -197,23 +197,18 @@ class UpdateProjectMembersAction(workflows.MembershipAction):
197 197
         # Figure out users & roles
198 198
         if project_id:
199 199
             try:
200
-                project_members = api.keystone.user_list(request,
201
-                    project=project_id)
200
+                users_roles = api.keystone.get_project_users_roles(request,
201
+                                                                   project_id)
202 202
             except Exception:
203
-                exceptions.handle(request, err_msg)
204
-
205
-            for user in project_members:
206
-                try:
207
-                    roles = api.keystone.roles_for_user(self.request,
208
-                                                        user.id,
209
-                                                        project_id)
210
-                except Exception:
211
-                    exceptions.handle(request,
212
-                                      err_msg,
213
-                                      redirect=reverse(INDEX_URL))
214
-                for role in roles:
215
-                    field_name = self.get_member_field_name(role.id)
216
-                    self.fields[field_name].initial.append(user.id)
203
+                exceptions.handle(request,
204
+                                  err_msg,
205
+                                  redirect=reverse(INDEX_URL))
206
+
207
+            for user_id in users_roles:
208
+                roles_ids = users_roles[user_id]
209
+                for role_id in roles_ids:
210
+                    field_name = self.get_member_field_name(role_id)
211
+                    self.fields[field_name].initial.append(user_id)
217 212
 
218 213
     class Meta:
219 214
         name = _("Project Members")

+ 27
- 0
openstack_dashboard/test/test_data/keystone_data.py View File

@@ -25,6 +25,7 @@ from keystoneclient.v2_0 import tenants
25 25
 from keystoneclient.v2_0 import users
26 26
 from keystoneclient.v3 import domains
27 27
 from keystoneclient.v3 import groups
28
+from keystoneclient.v3 import role_assignments
28 29
 
29 30
 from openstack_auth import user as auth_user
30 31
 
@@ -143,6 +144,7 @@ def data(TEST):
143 144
     TEST.users = utils.TestDataContainer()
144 145
     TEST.groups = utils.TestDataContainer()
145 146
     TEST.tenants = utils.TestDataContainer()
147
+    TEST.role_assignments = utils.TestDataContainer()
146 148
     TEST.roles = utils.TestDataContainer()
147 149
     TEST.ec2 = utils.TestDataContainer()
148 150
 
@@ -244,6 +246,31 @@ def data(TEST):
244 246
     group4 = groups.Group(groups.GroupManager(None), group_dict)
245 247
     TEST.groups.add(group, group2, group3, group4)
246 248
 
249
+    role_assignments_dict = {'user': {'id': '1'},
250
+                             'role': {'id': '1'},
251
+                             'scope': {'project': {'id': '1'}}}
252
+    role_assignment1 = role_assignments.RoleAssignment(
253
+        role_assignments.RoleAssignmentManager, role_assignments_dict)
254
+    role_assignments_dict = {'user': {'id': '2'},
255
+                             'role': {'id': '2'},
256
+                             'scope': {'project': {'id': '1'}}}
257
+    role_assignment2 = role_assignments.RoleAssignment(
258
+        role_assignments.RoleAssignmentManager, role_assignments_dict)
259
+    role_assignments_dict = {'group': {'id': '1'},
260
+                             'role': {'id': '2'},
261
+                             'scope': {'project': {'id': '1'}}}
262
+    role_assignment3 = role_assignments.RoleAssignment(
263
+        role_assignments.RoleAssignmentManager, role_assignments_dict)
264
+    role_assignments_dict = {'user': {'id': '3'},
265
+                             'role': {'id': '2'},
266
+                             'scope': {'project': {'id': '1'}}}
267
+    role_assignment4 = role_assignments.RoleAssignment(
268
+        role_assignments.RoleAssignmentManager, role_assignments_dict)
269
+    TEST.role_assignments.add(role_assignment1,
270
+                              role_assignment2,
271
+                              role_assignment3,
272
+                              role_assignment4)
273
+
247 274
     tenant_dict = {'id': "1",
248 275
                    'name': 'test_tenant',
249 276
                    'description': "a test tenant.",

Loading…
Cancel
Save