Merge "Add groups tab in project details view."
This commit is contained in:
commit
0202d17c88
@ -0,0 +1,33 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on 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 django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import forms
|
||||
from horizon import tables
|
||||
|
||||
from openstack_dashboard.dashboards.identity.groups \
|
||||
import tables as groups_tables
|
||||
|
||||
|
||||
class GroupsTable(groups_tables.GroupsTable):
|
||||
"""Display groups of the project."""
|
||||
roles = tables.Column(
|
||||
lambda obj: ", ".join(getattr(obj, 'roles', [])),
|
||||
verbose_name=_('Roles'),
|
||||
form_field=forms.CharField(
|
||||
widget=forms.Textarea(attrs={'rows': 4}),
|
||||
required=False))
|
||||
|
||||
class Meta(object):
|
||||
name = "groupstable"
|
||||
verbose_name = _("Groups")
|
@ -18,6 +18,8 @@ from horizon import tabs
|
||||
|
||||
from openstack_dashboard import api
|
||||
|
||||
from openstack_dashboard.dashboards.identity.projects.groups \
|
||||
import tables as groups_tables
|
||||
from openstack_dashboard.dashboards.identity.projects.users \
|
||||
import tables as users_tables
|
||||
|
||||
@ -169,6 +171,44 @@ class UsersTab(tabs.TableTab):
|
||||
return project_users.values()
|
||||
|
||||
|
||||
class GroupsTab(tabs.TableTab):
|
||||
"""Display groups member of the project. """
|
||||
table_classes = (groups_tables.GroupsTable,)
|
||||
name = _("Groups")
|
||||
slug = "groups"
|
||||
template_name = "horizon/common/_detail_table.html"
|
||||
preload = False
|
||||
|
||||
def get_groupstable_data(self):
|
||||
groups_in_project = []
|
||||
project = self.tab_group.kwargs['project']
|
||||
|
||||
try:
|
||||
# Get project_groups_roles: {group_id: [role_id_1, role_id_2]}
|
||||
project_groups_roles = api.keystone.get_project_groups_roles(
|
||||
self.request,
|
||||
project=project.id)
|
||||
# Get global roles and groups
|
||||
roles = api.keystone.role_list(self.request)
|
||||
# For keystone.group_list, we do not give the project_id because it
|
||||
# is ignored when called with admin creds.
|
||||
groups = api.keystone.group_list(self.request)
|
||||
groups = {group.id: group for group in groups}
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_("Unable to display the groups of this"
|
||||
" project."))
|
||||
else:
|
||||
# Construct Groups list, adding the role attribute
|
||||
for group_id in project_groups_roles:
|
||||
group = groups[group_id]
|
||||
group.roles = [role.name for role in roles
|
||||
if role.id in project_groups_roles[group_id]]
|
||||
groups_in_project.append(group)
|
||||
|
||||
return groups_in_project
|
||||
|
||||
|
||||
class ProjectDetailTabs(tabs.DetailTabsGroup):
|
||||
slug = "project_details"
|
||||
tabs = (OverviewTab, UsersTab,)
|
||||
tabs = (OverviewTab, UsersTab, GroupsTab,)
|
||||
|
@ -1486,6 +1486,94 @@ class DetailProjectViewTests(test.BaseAdminViewTests):
|
||||
self.mock_enabled_quotas.assert_called_once_with(test.IsHttpRequest())
|
||||
self.mock_role_list.assert_called_once_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({api.keystone: ("tenant_get",
|
||||
"get_project_groups_roles",
|
||||
"role_list",
|
||||
"group_list"),
|
||||
quotas: ('enabled_quotas',)})
|
||||
def test_detail_view_groups_tab(self):
|
||||
project = self.tenants.first()
|
||||
groups = self.groups.filter(domain_id=project.domain_id)
|
||||
role_assignments = self.role_assignments.filter(
|
||||
scope={'project': {'id': project.id}})
|
||||
# {group_id: [role_id1, role_id2]} as returned by the api
|
||||
project_groups_roles = self._project_group_roles(role_assignments)
|
||||
|
||||
# Prepare mocks
|
||||
self.mock_tenant_get.return_value = project
|
||||
self.mock_enabled_quotas.return_value = ('instances',)
|
||||
self.mock_get_project_groups_roles.return_value = project_groups_roles
|
||||
self.mock_group_list.return_value = groups
|
||||
self.mock_role_list.return_value = self.roles.list()
|
||||
|
||||
# Get project details view on group tab
|
||||
url = reverse('horizon:identity:projects:detail', args=[project.id])
|
||||
detail_view = tabs.ProjectDetailTabs(self.request, group=project)
|
||||
groups_tab_link = "?%s=%s" % (
|
||||
detail_view.param_name,
|
||||
detail_view.get_tab("groups").get_id()
|
||||
)
|
||||
url += groups_tab_link
|
||||
|
||||
res = self.client.get(url)
|
||||
|
||||
# Check the template expected has been used
|
||||
self.assertTemplateUsed(res,
|
||||
"horizon/common/_detail_table.html")
|
||||
|
||||
# Check the table content
|
||||
groups_expected = {'1': ["_member_"], }
|
||||
groups_id_observed = [group.id for group in
|
||||
res.context["groupstable_table"].data]
|
||||
|
||||
# Check the group is displayed
|
||||
self.assertItemsEqual(groups_id_observed, groups_expected.keys())
|
||||
|
||||
# Check the groups roles
|
||||
for group in res.context["groupstable_table"].data:
|
||||
self.assertEqual(groups_expected[group.id], group.roles)
|
||||
|
||||
self.mock_tenant_get.assert_called_once_with(test.IsHttpRequest(),
|
||||
self.tenant.id)
|
||||
self.mock_enabled_quotas.assert_called_once_with(test.IsHttpRequest())
|
||||
self.mock_role_list.assert_called_once_with(test.IsHttpRequest())
|
||||
self.mock_group_list.assert_called_once_with(test.IsHttpRequest())
|
||||
self.mock_get_project_groups_roles.assert_called_once_with(
|
||||
test.IsHttpRequest(), project=project.id)
|
||||
|
||||
@test.create_mocks({api.keystone: ("tenant_get",
|
||||
"get_project_groups_roles"),
|
||||
quotas: ('enabled_quotas',)})
|
||||
def test_detail_view_groups_tab_exception(self):
|
||||
project = self.tenants.first()
|
||||
|
||||
# Prepare mocks
|
||||
self.mock_tenant_get.return_value = project
|
||||
self.mock_enabled_quotas.return_value = ('instances',)
|
||||
self.mock_get_project_groups_roles.side_effect = \
|
||||
self.exceptions.keystone
|
||||
|
||||
# Get project details view on group tab
|
||||
url = reverse('horizon:identity:projects:detail', args=[project.id])
|
||||
detail_view = tabs.ProjectDetailTabs(self.request, group=project)
|
||||
groups_tab_link = "?%s=%s" % (
|
||||
detail_view.param_name,
|
||||
detail_view.get_tab("groups").get_id()
|
||||
)
|
||||
url += groups_tab_link
|
||||
res = self.client.get(url)
|
||||
|
||||
# Check the projects table is empty
|
||||
self.assertFalse(res.context["groupstable_table"].data)
|
||||
# Check one error message is displayed
|
||||
self.assertMessageCount(res, error=1)
|
||||
|
||||
self.mock_tenant_get.assert_called_once_with(test.IsHttpRequest(),
|
||||
self.tenant.id)
|
||||
self.mock_enabled_quotas.assert_called_once_with(test.IsHttpRequest())
|
||||
self.mock_get_project_groups_roles.assert_called_once_with(
|
||||
test.IsHttpRequest(), project=project.id)
|
||||
|
||||
|
||||
@tag('selenium')
|
||||
class SeleniumTests(test.SeleniumAdminTestCase, test.TestCase):
|
||||
|
Loading…
Reference in New Issue
Block a user