Merge "Add sort support to project list"
This commit is contained in:
commit
9184e19288
@ -96,6 +96,7 @@ List projects
|
||||
[--domain <domain>]
|
||||
[--user <user>]
|
||||
[--long]
|
||||
[--sort <key>[:<direction>,<key>:<direction>,..]]
|
||||
|
||||
.. option:: --domain <domain>
|
||||
|
||||
@ -113,6 +114,12 @@ List projects
|
||||
|
||||
List additional fields in output
|
||||
|
||||
.. option:: --sort <key>[:<direction>,<key>:<direction>,..]
|
||||
|
||||
Sort output by selected keys and directions (asc or desc) (default: asc),
|
||||
multiple keys and directions can be specified --sort
|
||||
<key>[:<direction>,<key>:<direction>,..]
|
||||
|
||||
project set
|
||||
-----------
|
||||
|
||||
|
@ -150,6 +150,13 @@ class ListProject(command.Lister):
|
||||
default=False,
|
||||
help=_('List additional fields in output'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--sort',
|
||||
metavar='<key>[:<direction>]',
|
||||
help=_('Sort output by selected keys and directions (asc or desc) '
|
||||
'(default: asc), repeat this option to specify multiple '
|
||||
'keys and directions.'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
@ -158,6 +165,8 @@ class ListProject(command.Lister):
|
||||
else:
|
||||
columns = ('ID', 'Name')
|
||||
data = self.app.client_manager.identity.tenants.list()
|
||||
if parsed_args.sort:
|
||||
data = utils.sort_items(data, parsed_args.sort)
|
||||
return (columns,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
|
@ -194,6 +194,13 @@ class ListProject(command.Lister):
|
||||
default=False,
|
||||
help=_('List additional fields in output'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--sort',
|
||||
metavar='<key>[:<direction>]',
|
||||
help=_('Sort output by selected keys and directions (asc or desc) '
|
||||
'(default: asc), repeat this option to specify multiple '
|
||||
'keys and directions.'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
@ -222,6 +229,8 @@ class ListProject(command.Lister):
|
||||
kwargs['user'] = user_id
|
||||
|
||||
data = identity_client.projects.list(**kwargs)
|
||||
if parsed_args.sort:
|
||||
data = utils.sort_items(data, parsed_args.sort)
|
||||
return (columns,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
|
@ -26,6 +26,7 @@ from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
|
||||
class TestProject(identity_fakes.TestIdentityv2):
|
||||
|
||||
fake_project = identity_fakes.FakeProject.create_one_project()
|
||||
fake_projects = identity_fakes.FakeProject.create_projects()
|
||||
|
||||
columns = (
|
||||
'description',
|
||||
@ -39,6 +40,12 @@ class TestProject(identity_fakes.TestIdentityv2):
|
||||
fake_project.id,
|
||||
fake_project.name,
|
||||
)
|
||||
datalists = (
|
||||
(fake_projects[0].description, True,
|
||||
fake_projects[0].id, fake_projects[0].name,),
|
||||
(fake_projects[1].description, True,
|
||||
fake_projects[1].id, fake_projects[1].name,),
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(TestProject, self).setUp()
|
||||
@ -386,6 +393,35 @@ class TestProjectList(TestProject):
|
||||
), )
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
|
||||
def test_project_list_sort(self):
|
||||
self.projects_mock.list.return_value = self.fake_projects
|
||||
|
||||
arglist = ['--sort', 'name:asc', ]
|
||||
verifylist = []
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
# In base command class Lister in cliff, abstract method take_action()
|
||||
# returns a tuple containing the column names and an iterable
|
||||
# containing the data to be listed.
|
||||
(columns, data) = self.cmd.take_action(parsed_args)
|
||||
self.projects_mock.list.assert_called_with()
|
||||
|
||||
collist = ('ID', 'Name')
|
||||
self.assertEqual(collist, columns)
|
||||
|
||||
if self.fake_projects[0].name > self.fake_projects[1].name:
|
||||
datalists = (
|
||||
(self.fake_projects[1].id, self.fake_projects[1].name),
|
||||
(self.fake_projects[0].id, self.fake_projects[0].name),
|
||||
)
|
||||
else:
|
||||
datalists = (
|
||||
(self.fake_projects[0].id, self.fake_projects[0].name),
|
||||
(self.fake_projects[1].id, self.fake_projects[1].name),
|
||||
)
|
||||
|
||||
self.assertEqual(datalists, tuple(data))
|
||||
|
||||
|
||||
class TestProjectSet(TestProject):
|
||||
|
||||
|
@ -622,6 +622,23 @@ class FakeProject(object):
|
||||
loaded=True)
|
||||
return project
|
||||
|
||||
@staticmethod
|
||||
def create_projects(attrs=None, count=2):
|
||||
"""Create multiple fake projects.
|
||||
|
||||
:param Dictionary attrs:
|
||||
A dictionary with all attributes
|
||||
:param int count:
|
||||
The number of projects to fake
|
||||
:return:
|
||||
A list of FakeResource objects faking the projects
|
||||
"""
|
||||
|
||||
projects = []
|
||||
for i in range(0, count):
|
||||
projects.append(FakeProject.create_one_project(attrs))
|
||||
return projects
|
||||
|
||||
|
||||
class FakeDomain(object):
|
||||
"""Fake one or more domain."""
|
||||
|
@ -479,6 +479,7 @@ class TestProjectList(TestProject):
|
||||
domain = identity_fakes.FakeDomain.create_one_domain()
|
||||
project = identity_fakes.FakeProject.create_one_project(
|
||||
attrs={'domain_id': domain.id})
|
||||
projects = identity_fakes.FakeProject.create_projects()
|
||||
|
||||
columns = (
|
||||
'ID',
|
||||
@ -490,6 +491,12 @@ class TestProjectList(TestProject):
|
||||
project.name,
|
||||
),
|
||||
)
|
||||
datalists = (
|
||||
(projects[0].description, True,
|
||||
projects[0].id, projects[0].name,),
|
||||
(projects[1].description, True,
|
||||
projects[1].id, projects[1].name,),
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(TestProjectList, self).setUp()
|
||||
@ -580,6 +587,36 @@ class TestProjectList(TestProject):
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist, tuple(data))
|
||||
|
||||
def test_project_list_sort(self):
|
||||
self.projects_mock.list.return_value = self.projects
|
||||
|
||||
arglist = ['--sort', 'name:asc', ]
|
||||
verifylist = []
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
# In base command class Lister in cliff, abstract method take_action()
|
||||
# returns a tuple containing the column names and an iterable
|
||||
# containing the data to be listed.
|
||||
(columns, data) = self.cmd.take_action(parsed_args)
|
||||
self.projects_mock.list.assert_called_with()
|
||||
|
||||
collist = ('ID', 'Name')
|
||||
self.assertEqual(collist, columns)
|
||||
|
||||
if self.projects[0].name > self.projects[1].name:
|
||||
datalists = (
|
||||
(self.projects[1].id, self.projects[1].name),
|
||||
(self.projects[0].id, self.projects[0].name),
|
||||
)
|
||||
else:
|
||||
datalists = (
|
||||
(self.projects[0].id, self.projects[0].name),
|
||||
(self.projects[1].id, self.projects[1].name),
|
||||
)
|
||||
|
||||
self.assertEqual(datalists, tuple(data))
|
||||
|
||||
|
||||
class TestProjectSet(TestProject):
|
||||
|
||||
|
6
releasenotes/notes/bug-1596818-d4cd93dd4d38d3d6.yaml
Normal file
6
releasenotes/notes/bug-1596818-d4cd93dd4d38d3d6.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add ``--sort`` support to ``project list`` by sorting items in client side
|
||||
By default project list will be sorted by name.
|
||||
[Bug `1596818 <https://bugs.launchpad.net/bugs/1596818>`_]
|
Loading…
Reference in New Issue
Block a user