Merge "Support pagination and filtering for routing list operations"
This commit is contained in:
commit
630c9a384a
|
@ -14,6 +14,7 @@
|
|||
#
|
||||
|
||||
import copy
|
||||
from oslo_utils import timeutils
|
||||
import testtools
|
||||
import uuid
|
||||
|
||||
|
@ -114,6 +115,8 @@ class FakeRouting(object):
|
|||
'project_id': uuid.uuid4().hex,
|
||||
'resource_type': 'network',
|
||||
'id': uuid.uuid4().hex,
|
||||
'created_at': str(timeutils.utcnow()),
|
||||
'updated_at': str(timeutils.utcnow()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,10 +90,11 @@ class TestListRouting(_TestRoutingCommand):
|
|||
|
||||
def test_list(self):
|
||||
_routings = utils.FakeRouting.create_multiple_routings()
|
||||
|
||||
for routing in _routings:
|
||||
routing.pop('top_id')
|
||||
routing.pop('bottom_id')
|
||||
routing.pop('project_id')
|
||||
for key in ('top_id', 'bottom_id', 'project_id'):
|
||||
routing.pop(key)
|
||||
|
||||
self.routing_manager.list = mock.Mock(
|
||||
return_value={'routings': _routings})
|
||||
parsed_args = self.check_parser(self.cmd)
|
||||
|
@ -102,6 +103,72 @@ class TestListRouting(_TestRoutingCommand):
|
|||
self.assertEqual(self.columns, sorted(columns))
|
||||
self.assertEqual(len(_routings), len(data))
|
||||
|
||||
def test_list_with_filters(self):
|
||||
_routing = utils.FakeRouting.create_single_routing()
|
||||
_routing = _routing['routing']
|
||||
|
||||
# we filter the routings by the following fields
|
||||
# given values of _routing, then only single item _routing
|
||||
# is retrieved.
|
||||
arglist = [
|
||||
'--top-id', _routing['top_id'],
|
||||
'--bottom-id', _routing['bottom_id'],
|
||||
'--pod-id', _routing['pod_id'],
|
||||
'--project-id', _routing['project_id'],
|
||||
'--resource-type', _routing['resource_type'],
|
||||
'--created-at', _routing['created_at'],
|
||||
'--updated-at', _routing['updated_at'],
|
||||
]
|
||||
verifylist = [
|
||||
('top_id', _routing['top_id']),
|
||||
('bottom_id', _routing['bottom_id']),
|
||||
('pod_id', _routing['pod_id']),
|
||||
('project_id', _routing['project_id']),
|
||||
('resource_type', _routing['resource_type']),
|
||||
('created_at', _routing['created_at']),
|
||||
('updated_at', _routing['updated_at']),
|
||||
]
|
||||
for key in ('top_id', 'bottom_id', 'project_id'):
|
||||
_routing.pop(key)
|
||||
|
||||
self.routing_manager.list = mock.Mock(
|
||||
return_value={'routings': [_routing]})
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
columns, data = (self.cmd.take_action(parsed_args))
|
||||
|
||||
self.assertEqual(self.columns, sorted(columns))
|
||||
self.assertEqual(1, len(data))
|
||||
|
||||
def test_throw_exception(self):
|
||||
arglist = [
|
||||
'--resource-type', 'fake_resource_type',
|
||||
]
|
||||
verifylist = []
|
||||
self.assertRaises(utils.ParserException, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
||||
|
||||
def test_list_with_pagination(self):
|
||||
_routings = utils.FakeRouting.create_multiple_routings(count=3)
|
||||
arglist = [
|
||||
'--page-size', '2',
|
||||
'--marker', _routings[0]['id'],
|
||||
]
|
||||
verifylist = [
|
||||
('limit', 2),
|
||||
('marker', _routings[0]['id']),
|
||||
]
|
||||
for routing in _routings:
|
||||
for key in ('top_id', 'bottom_id', 'project_id'):
|
||||
routing.pop(key)
|
||||
|
||||
self.routing_manager.list = mock.Mock(
|
||||
return_value={'routings': _routings[1:]})
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
columns, data = (self.cmd.take_action(parsed_args))
|
||||
|
||||
self.assertEqual(self.columns, sorted(columns))
|
||||
self.assertEqual(2, len(data))
|
||||
|
||||
|
||||
class TestDeleteRouting(_TestRoutingCommand, utils.TestCommandWithoutOptions):
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ from tricircleclient.v1 import base
|
|||
|
||||
class RoutingManager(base.Manager):
|
||||
|
||||
def list(self, search_opts=None):
|
||||
def list(self, path):
|
||||
"""Get a list of Resource Routings."""
|
||||
return self._get(
|
||||
'/routings',
|
||||
path,
|
||||
headers={'Content-Type': "application/json"}).json()
|
||||
|
||||
def create(self, routing):
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
from osc_lib.command import command
|
||||
from oslo_log import log as logging
|
||||
from six.moves.urllib import parse
|
||||
|
||||
from tricircleclient import utils
|
||||
|
||||
|
@ -30,17 +31,114 @@ def _routing_from_args(parsed_args):
|
|||
return {'routing': result}
|
||||
|
||||
|
||||
def _add_pagination_argument(parser):
|
||||
parser.add_argument(
|
||||
'-P', '--page-size',
|
||||
dest='limit', metavar='SIZE', type=int,
|
||||
help="Maximum number of routings to return",
|
||||
default=None)
|
||||
|
||||
|
||||
def _add_marker_argument(parser):
|
||||
parser.add_argument(
|
||||
'-M', '--marker',
|
||||
dest='marker', metavar='MARKER', type=str,
|
||||
help="Starting point for next routing list "
|
||||
"that shares same routing id",
|
||||
default=None)
|
||||
|
||||
|
||||
def _add_filtering_arguments(parser):
|
||||
parser.add_argument(
|
||||
'--id',
|
||||
dest='id', metavar='id', type=int,
|
||||
help="Uuid of a routing",
|
||||
default=None)
|
||||
parser.add_argument(
|
||||
'--top-id',
|
||||
dest='top_id', metavar='top_id', type=str,
|
||||
help="Resource id on Central Neutron",
|
||||
default=None)
|
||||
parser.add_argument(
|
||||
'--bottom-id',
|
||||
dest='bottom_id', metavar='bottom_id', type=str,
|
||||
help="Resource id on Local Neutron",
|
||||
default=None)
|
||||
parser.add_argument(
|
||||
'--pod-id',
|
||||
dest='pod_id', metavar='pod_id', type=str,
|
||||
help="Uuid of a pod",
|
||||
default=None)
|
||||
parser.add_argument(
|
||||
'--project-id',
|
||||
dest='project_id', metavar='project_id', type=str,
|
||||
help="Uuid of a project object in Keystone",
|
||||
default=None)
|
||||
parser.add_argument(
|
||||
'--resource-type',
|
||||
dest='resource_type', metavar='resource_type', type=str,
|
||||
choices=['network', 'subnet', 'port', 'router', 'security_group'],
|
||||
help="Available resource types",
|
||||
default=None)
|
||||
parser.add_argument(
|
||||
'--created-at',
|
||||
dest='created_at', metavar='created_at', type=str,
|
||||
help="Create time of the resource routing",
|
||||
default=None)
|
||||
parser.add_argument(
|
||||
'--updated-at',
|
||||
dest='updated_at', metavar='updated_at', type=str,
|
||||
help="Update time of the resource routing",
|
||||
default=None)
|
||||
|
||||
|
||||
def _add_search_options(parsed_args):
|
||||
search_opts = {}
|
||||
for key in ('limit', 'marker', 'id', 'top_id', 'bottom_id', 'pod_id',
|
||||
'project_id', 'resource_type', 'created_at', 'updated_at'):
|
||||
value = getattr(parsed_args, key, None)
|
||||
if value is not None:
|
||||
search_opts[key] = value
|
||||
return search_opts
|
||||
|
||||
|
||||
def _prepare_query_string(params):
|
||||
"""Convert dict params to query string"""
|
||||
params = sorted(params.items(), key=lambda x: x[0])
|
||||
return '?%s' % parse.urlencode(params) if params else ''
|
||||
|
||||
|
||||
class ListRoutings(command.Lister):
|
||||
"""Lists Routings"""
|
||||
|
||||
COLS = ('id', 'pod_id', 'resource_type')
|
||||
path = '/routings'
|
||||
|
||||
pagination_support = True
|
||||
marker_support = True
|
||||
|
||||
log = logging.getLogger(__name__ + ".ListRoutings")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListRoutings, self).get_parser(prog_name)
|
||||
|
||||
if self.pagination_support:
|
||||
_add_pagination_argument(parser)
|
||||
if self.marker_support:
|
||||
_add_marker_argument(parser)
|
||||
_add_filtering_arguments(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
client = self.app.client_manager.multiregion_networking
|
||||
data = client.routing.list()
|
||||
|
||||
# add pagination/marker/filter to list operation
|
||||
search_opts = _add_search_options(parsed_args)
|
||||
self.path += _prepare_query_string(search_opts)
|
||||
|
||||
data = client.routing.list(self.path)
|
||||
remap = {'id': 'Id',
|
||||
'pod_id': 'Pod Id',
|
||||
'resource_type': 'Resource Type'}
|
||||
|
|
Loading…
Reference in New Issue