Add limit and offset to server-groups list

Via `limit` and `offset` arguments, Nova API now support pagination
to display server groups. But our novaclient hasn't implemented yet
in current version. This patch introduce `--limit` and `--offset`
options to `nova server-group-list` subcommand, which can make up for
the above issue.

Change-Id: I371d4c2e74a8e6bfc8a7529de35668490cb0e44d
Closes-Bug: #1648835
This commit is contained in:
int32bit 2016-12-10 01:29:28 +08:00
parent aa2feca675
commit 50d83a4de2
6 changed files with 135 additions and 23 deletions

View File

@ -50,12 +50,51 @@ class Fixture(base.Fixture):
}
]
other_project_server_groups = [
{
"members": [],
"metadata": {},
"id": "11111111-1111-1111-1111-111111111111",
"policies": [],
"name": "ig4"
},
{
"members": [],
"metadata": {},
"id": "22222222-2222-2222-2222-222222222222",
"policies": ["anti-affinity"],
"name": "ig5"
},
{
"members": [],
"metadata": {"key": "value"},
"id": "33333333-3333-3333-3333-333333333333",
"policies": [], "name": "ig6"
},
{
"members": ["2dccb4a1-02b9-482a-aa23-5799490d6f5d"],
"metadata": {},
"id": "44444444-4444-4444-4444-444444444444",
"policies": ["anti-affinity"],
"name": "ig5"
}
]
headers = self.json_headers
self.requests_mock.get(self.url(),
json={'server_groups': server_groups},
headers=headers)
self.requests_mock.get(self.url(all_projects=True),
json={'server_groups': server_groups
+ other_project_server_groups},
headers=headers)
self.requests_mock.get(self.url(limit=2, offset=1),
json={'server_groups': server_groups[1:3]},
headers=headers)
server = server_groups[0]
def _register(method, *args):

View File

@ -2162,22 +2162,43 @@ class FakeHTTPClient(base_client.HTTPClient):
# Server Groups
#
def get_os_server_groups(self, *kw):
return (200, {},
{"server_groups": [
{"members": [], "metadata": {},
"id": "2cbd51f4-fafe-4cdb-801b-cf913a6f288b",
"policies": [], "name": "ig1"},
{"members": [], "metadata": {},
"id": "4473bb03-4370-4bfb-80d3-dc8cffc47d94",
"policies": ["anti-affinity"], "name": "ig2"},
{"members": [], "metadata": {"key": "value"},
"id": "31ab9bdb-55e1-4ac3-b094-97eeb1b65cc4",
"policies": [], "name": "ig3"},
{"members": ["2dccb4a1-02b9-482a-aa23-5799490d6f5d"],
"metadata": {},
"id": "4890bb03-7070-45fb-8453-d34556c87d94",
"policies": ["anti-affinity"], "name": "ig2"}]})
def get_os_server_groups(self, **kw):
server_groups = [
{"members": [], "metadata": {},
"id": "2cbd51f4-fafe-4cdb-801b-cf913a6f288b",
"policies": [], "name": "ig1"},
{"members": [], "metadata": {},
"id": "4473bb03-4370-4bfb-80d3-dc8cffc47d94",
"policies": ["anti-affinity"], "name": "ig2"},
{"members": [], "metadata": {"key": "value"},
"id": "31ab9bdb-55e1-4ac3-b094-97eeb1b65cc4",
"policies": [], "name": "ig3"},
{"members": ["2dccb4a1-02b9-482a-aa23-5799490d6f5d"],
"metadata": {},
"id": "4890bb03-7070-45fb-8453-d34556c87d94",
"policies": ["anti-affinity"], "name": "ig2"}]
other_project_server_groups = [
{"members": [], "metadata": {},
"id": "11111111-1111-1111-1111-111111111111",
"policies": [], "name": "ig4"},
{"members": [], "metadata": {},
"id": "22222222-2222-2222-2222-222222222222",
"policies": ["anti-affinity"], "name": "ig5"},
{"members": [], "metadata": {"key": "value"},
"id": "31ab9bdb-55e1-4ac3-b094-97eeb1b65cc4",
"policies": [], "name": "ig6"},
{"members": ["33333333-3333-3333-3333-333333333333"],
"metadata": {},
"id": "44444444-4444-4444-4444-444444444444",
"policies": ["anti-affinity"], "name": "ig5"}]
if kw.get("all_projects", False):
server_groups.extend(other_project_server_groups)
limit = int(kw.get("limit", 1000))
offset = int(kw.get("offset", 0))
server_groups = server_groups[offset:limit + 1]
return (200, {}, {"server_groups": server_groups})
def _return_server_group(self):
r = {'server_group':

View File

@ -30,6 +30,7 @@ class ServerGroupsTest(utils.FixturedTestCase):
result = self.cs.server_groups.list()
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called('GET', '/os-server-groups')
self.assertEqual(4, len(result))
for server_group in result:
self.assertIsInstance(server_group,
server_groups.ServerGroup)
@ -37,11 +38,23 @@ class ServerGroupsTest(utils.FixturedTestCase):
def test_list_server_groups_with_all_projects(self):
result = self.cs.server_groups.list(all_projects=True)
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called('GET', '/os-server-groups?all_projects')
self.assert_called('GET', '/os-server-groups?all_projects=True')
self.assertEqual(8, len(result))
for server_group in result:
self.assertIsInstance(server_group,
server_groups.ServerGroup)
def test_list_server_groups_with_limit_and_offset(self):
all_groups = self.cs.server_groups.list()
result = self.cs.server_groups.list(limit=2, offset=1)
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called('GET', '/os-server-groups?limit=2&offset=1')
self.assertEqual(2, len(result))
for server_group in result:
self.assertIsInstance(server_group,
server_groups.ServerGroup)
self.assertEqual(all_groups[1:3], result)
def test_create_server_group(self):
kwargs = {'name': 'ig1',
'policies': ['anti-affinity']}

View File

@ -3149,7 +3149,11 @@ class ShellTest(utils.TestCase):
def test_list_server_group_with_all_projects(self):
self.run_command('server-group-list --all-projects')
self.assert_called('GET', '/os-server-groups?all_projects')
self.assert_called('GET', '/os-server-groups?all_projects=True')
def test_list_server_group_with_limit_and_offset(self):
self.run_command('server-group-list --limit 20 --offset 5')
self.assert_called('GET', '/os-server-groups?limit=20&offset=5')
def test_list_server_os_virtual_interfaces(self):
self.run_command('virtual-interface-list 1234')

View File

@ -17,6 +17,8 @@
Server group interface.
"""
from six.moves.urllib import parse
from novaclient import base
@ -43,13 +45,27 @@ class ServerGroupsManager(base.ManagerWithFind):
"""
resource_class = ServerGroup
def list(self, all_projects=False):
def list(self, all_projects=False, limit=None, offset=None):
"""Get a list of all server groups.
:rtype: list of :class:`ServerGroup`.
:param all_projects: Lists server groups for all projects. (optional)
:param limit: Maximum number of server groups to return. (optional)
:param offset: Use with `limit` to return a slice of server
groups. `offset` is where to start in the groups
list. (optional)
:returns: list of :class:`ServerGroup`.
"""
all = '?all_projects' if all_projects else ''
return self._list('/os-server-groups%s' % all, 'server_groups')
qparams = {}
if all_projects:
qparams['all_projects'] = bool(all_projects)
if limit:
qparams['limit'] = int(limit)
if offset:
qparams['offset'] = int(offset)
qparams = sorted(qparams.items(), key=lambda x: x[0])
query_string = "?%s" % parse.urlencode(qparams) if qparams else ""
return self._list('/os-server-groups%s' % query_string,
'server_groups')
def get(self, id):
"""Get a specific server group.

View File

@ -5035,6 +5035,23 @@ def _print_server_group_details(cs, server_group): # noqa
utils.print_list(server_group, columns)
@utils.arg(
'--limit',
dest='limit',
metavar='<limit>',
type=int,
default=None,
help=_("Maximum number of server groups to display. If limit is bigger"
"than 'CONF.api.max_limit' option of Nova API, limit"
"'CONF.api.max_limit' will be used instead."))
@utils.arg(
'--offset',
dest='offset',
metavar='<offset>',
type=int,
default=None,
help=_('The offset of groups list to display; use with limit to '
'return a slice of server groups.'))
@utils.arg(
'--all-projects',
dest='all_projects',
@ -5043,7 +5060,9 @@ def _print_server_group_details(cs, server_group): # noqa
help=_('Display server groups from all projects (Admin only).'))
def do_server_group_list(cs, args):
"""Print a list of all server groups."""
server_groups = cs.server_groups.list(args.all_projects)
server_groups = cs.server_groups.list(all_projects=args.all_projects,
limit=args.limit,
offset=args.offset)
_print_server_group_details(cs, server_groups)