Set default columns in ext-list
Previously ext-list does not inherits ListCommand base class for listing and cannot specify columns to display. This commit changes ext-list to use ListCommand and adds a unit test for extensions. This also changes the default value of _formatters in ListCommand to {}. By this subclasses no longer override _formatters unless required. Fixes bug 1161866 Change-Id: Ifd9ab54d4e84a2b7a1d7eecd67f6270ec643db1d
This commit is contained in:
parent
de7fd2b2c0
commit
b95000665d
|
@ -17,79 +17,28 @@
|
|||
|
||||
import logging
|
||||
|
||||
from cliff import lister
|
||||
from cliff import show
|
||||
|
||||
from quantumclient.common import utils
|
||||
from quantumclient.quantum.v2_0 import QuantumCommand
|
||||
from quantumclient.quantum import v2_0 as cmd_base
|
||||
|
||||
|
||||
class ListExt(QuantumCommand, lister.Lister):
|
||||
"""List all exts."""
|
||||
class ListExt(cmd_base.ListCommand):
|
||||
"""List all extensions."""
|
||||
|
||||
api = 'network'
|
||||
resource = 'extension'
|
||||
log = logging.getLogger(__name__ + '.ListExt')
|
||||
_formatters = None
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListExt, self).get_parser(prog_name)
|
||||
return parser
|
||||
|
||||
def get_data(self, parsed_args):
|
||||
self.log.debug('get_data(%s)' % parsed_args)
|
||||
quantum_client = self.get_client()
|
||||
search_opts = {}
|
||||
quantum_client.format = parsed_args.request_format
|
||||
obj_lister = getattr(quantum_client,
|
||||
"list_%ss" % self.resource)
|
||||
data = obj_lister(**search_opts)
|
||||
info = []
|
||||
collection = self.resource + "s"
|
||||
if collection in data:
|
||||
info = data[collection]
|
||||
_columns = len(info) > 0 and sorted(info[0].keys()) or []
|
||||
return (_columns, (utils.get_item_properties(s, _columns)
|
||||
for s in info))
|
||||
list_columns = ['alias', 'name']
|
||||
|
||||
|
||||
class ShowExt(QuantumCommand, show.ShowOne):
|
||||
"""Show information of a given resource
|
||||
class ShowExt(cmd_base.ShowCommand):
|
||||
"""Show information of a given resource."""
|
||||
|
||||
"""
|
||||
api = 'network'
|
||||
resource = "extension"
|
||||
log = logging.getLogger(__name__ + '.ShowExt')
|
||||
allow_names = False
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowExt, self).get_parser(prog_name)
|
||||
parser = super(cmd_base.ShowCommand, self).get_parser(prog_name)
|
||||
cmd_base.add_show_list_common_argument(parser)
|
||||
parser.add_argument(
|
||||
'ext_alias', metavar='ext-alias',
|
||||
'id', metavar='EXT-ALIAS',
|
||||
help='the extension alias')
|
||||
return parser
|
||||
|
||||
def get_data(self, parsed_args):
|
||||
self.log.debug('get_data(%s)' % parsed_args)
|
||||
quantum_client = self.get_client()
|
||||
quantum_client.format = parsed_args.request_format
|
||||
params = {}
|
||||
obj_shower = getattr(quantum_client,
|
||||
"show_%s" % self.resource)
|
||||
data = obj_shower(parsed_args.ext_alias, **params)
|
||||
if self.resource in data:
|
||||
for k, v in data[self.resource].iteritems():
|
||||
if isinstance(v, list):
|
||||
value = ""
|
||||
for _item in v:
|
||||
if value:
|
||||
value += "\n"
|
||||
if isinstance(_item, dict):
|
||||
value += utils.dumps(_item)
|
||||
else:
|
||||
value += str(_item)
|
||||
data[self.resource][k] = value
|
||||
elif v is None:
|
||||
data[self.resource][k] = ''
|
||||
return zip(*sorted(data[self.resource].iteritems()))
|
||||
else:
|
||||
return None
|
||||
|
|
|
@ -31,7 +31,6 @@ class ListFloatingIP(ListCommand):
|
|||
|
||||
resource = 'floatingip'
|
||||
log = logging.getLogger(__name__ + '.ListFloatingIP')
|
||||
_formatters = {}
|
||||
list_columns = ['id', 'fixed_ip_address', 'floating_ip_address',
|
||||
'port_id']
|
||||
pagination_support = True
|
||||
|
|
|
@ -28,7 +28,6 @@ class ListHealthMonitor(quantumv20.ListCommand):
|
|||
resource = 'health_monitor'
|
||||
log = logging.getLogger(__name__ + '.ListHealthMonitor')
|
||||
list_columns = ['id', 'type', 'admin_state_up', 'status']
|
||||
_formatters = {}
|
||||
pagination_support = True
|
||||
sorting_support = True
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ class ListMember(quantumv20.ListCommand):
|
|||
list_columns = [
|
||||
'id', 'address', 'protocol_port', 'admin_state_up', 'status'
|
||||
]
|
||||
_formatters = {}
|
||||
pagination_support = True
|
||||
sorting_support = True
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ class ListPool(quantumv20.ListCommand):
|
|||
log = logging.getLogger(__name__ + '.ListPool')
|
||||
list_columns = ['id', 'name', 'lb_method', 'protocol',
|
||||
'admin_state_up', 'status']
|
||||
_formatters = {}
|
||||
pagination_support = True
|
||||
sorting_support = True
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ class ListVip(quantumv20.ListCommand):
|
|||
log = logging.getLogger(__name__ + '.ListVip')
|
||||
list_columns = ['id', 'name', 'algorithm', 'address', 'protocol',
|
||||
'admin_state_up', 'status']
|
||||
_formatters = {}
|
||||
pagination_support = True
|
||||
sorting_support = True
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ class ListQoSQueue(quantumv20.ListCommand):
|
|||
|
||||
resource = 'qos_queue'
|
||||
log = logging.getLogger(__name__ + '.ListQoSQueue')
|
||||
_formatters = {}
|
||||
list_columns = ['id', 'name', 'min', 'max',
|
||||
'qos_marking', 'dscp', 'default']
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ class ListNetworkGateway(quantumv20.ListCommand):
|
|||
"""List network gateways for a given tenant."""
|
||||
|
||||
resource = RESOURCE
|
||||
_formatters = {}
|
||||
log = logging.getLogger(__name__ + '.ListNetworkGateway')
|
||||
list_columns = ['id', 'name']
|
||||
|
||||
|
|
|
@ -70,7 +70,6 @@ class ListQuota(QuantumCommand, lister.Lister):
|
|||
api = 'network'
|
||||
resource = 'quota'
|
||||
log = logging.getLogger(__name__ + '.ListQuota')
|
||||
_formatters = None
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListQuota, self).get_parser(prog_name)
|
||||
|
|
|
@ -26,7 +26,6 @@ class ListSecurityGroup(quantumv20.ListCommand):
|
|||
|
||||
resource = 'security_group'
|
||||
log = logging.getLogger(__name__ + '.ListSecurityGroup')
|
||||
_formatters = {}
|
||||
list_columns = ['id', 'name', 'description']
|
||||
pagination_support = True
|
||||
sorting_support = True
|
||||
|
@ -103,7 +102,6 @@ class ListSecurityGroupRule(quantumv20.ListCommand):
|
|||
|
||||
resource = 'security_group_rule'
|
||||
log = logging.getLogger(__name__ + '.ListSecurityGroupRule')
|
||||
_formatters = {}
|
||||
list_columns = ['id', 'security_group_id', 'direction', 'protocol',
|
||||
'remote_ip_prefix', 'remote_group_id']
|
||||
replace_rules = {'security_group_id': 'security_group',
|
||||
|
|
|
@ -153,8 +153,8 @@ class Client(object):
|
|||
subnet_path = "/subnets/%s"
|
||||
quotas_path = "/quotas"
|
||||
quota_path = "/quotas/%s"
|
||||
exts_path = "/extensions"
|
||||
ext_path = "/extensions/%s"
|
||||
extensions_path = "/extensions"
|
||||
extension_path = "/extensions/%s"
|
||||
routers_path = "/routers"
|
||||
router_path = "/routers/%s"
|
||||
floatingips_path = "/floatingips"
|
||||
|
@ -245,12 +245,12 @@ class Client(object):
|
|||
@APIParamsCall
|
||||
def list_extensions(self, **_params):
|
||||
"""Fetch a list of all exts on server side."""
|
||||
return self.get(self.exts_path, params=_params)
|
||||
return self.get(self.extensions_path, params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def show_extension(self, ext_alias, **_params):
|
||||
"""Fetch a list of all exts on server side."""
|
||||
return self.get(self.ext_path % ext_alias, params=_params)
|
||||
return self.get(self.extension_path % ext_alias, params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def list_ports(self, retrieve_all=True, **_params):
|
||||
|
|
|
@ -145,6 +145,7 @@ class CLITestV20Base(testtools.TestCase):
|
|||
|
||||
format = 'json'
|
||||
test_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
|
||||
id_field = 'id'
|
||||
|
||||
def _find_resourceid(self, client, resource, name_or_id):
|
||||
return name_or_id
|
||||
|
@ -206,7 +207,7 @@ class CLITestV20Base(testtools.TestCase):
|
|||
for i in xrange(len(position_names)):
|
||||
body[resource].update({position_names[i]: position_values[i]})
|
||||
ress = {resource:
|
||||
{'id': myid}, }
|
||||
{self.id_field: myid}, }
|
||||
if name:
|
||||
ress[resource].update({'name': name})
|
||||
self.client.format = self.format
|
||||
|
@ -253,12 +254,16 @@ class CLITestV20Base(testtools.TestCase):
|
|||
|
||||
def _test_list_resources(self, resources, cmd, detail=False, tags=[],
|
||||
fields_1=[], fields_2=[], page_size=None,
|
||||
sort_key=[], sort_dir=[]):
|
||||
sort_key=[], sort_dir=[], response_contents=None):
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
reses = {resources: [{'id': 'myid1', },
|
||||
{'id': 'myid2', }, ], }
|
||||
if response_contents is None:
|
||||
contents = [{self.id_field: 'myid1', },
|
||||
{self.id_field: 'myid2', }, ]
|
||||
else:
|
||||
contents = response_contents
|
||||
reses = {resources: contents}
|
||||
self.client.format = self.format
|
||||
resstr = self.client.serialize(reses)
|
||||
# url method body
|
||||
|
@ -335,7 +340,9 @@ class CLITestV20Base(testtools.TestCase):
|
|||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
_str = self.fake_stdout.make_string()
|
||||
self.assertTrue('myid1' in _str)
|
||||
if response_contents is None:
|
||||
self.assertTrue('myid1' in _str)
|
||||
return _str
|
||||
|
||||
def _test_list_resources_with_pagination(self, resources, cmd):
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
|
@ -399,8 +406,8 @@ class CLITestV20Base(testtools.TestCase):
|
|||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
query = "&".join(["fields=%s" % field for field in fields])
|
||||
expected_res = {resource:
|
||||
{'id': myid,
|
||||
'name': 'myname', }, }
|
||||
{self.id_field: myid,
|
||||
'name': 'myname', }, }
|
||||
self.client.format = self.format
|
||||
resstr = self.client.serialize(expected_res)
|
||||
path = getattr(self.client, resource + "_path")
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 NEC Corporation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sys
|
||||
|
||||
from quantumclient.quantum.v2_0.extension import ListExt
|
||||
from quantumclient.quantum.v2_0.extension import ShowExt
|
||||
from tests.unit.test_cli20 import CLITestV20Base
|
||||
from tests.unit.test_cli20 import MyApp
|
||||
|
||||
|
||||
class CLITestV20Extension(CLITestV20Base):
|
||||
id_field = 'alias'
|
||||
|
||||
def test_list_extensions(self):
|
||||
resources = 'extensions'
|
||||
cmd = ListExt(MyApp(sys.stdout), None)
|
||||
contents = [{'alias': 'ext1', 'name': 'name1', 'other': 'other1'},
|
||||
{'alias': 'ext2', 'name': 'name2', 'other': 'other2'}]
|
||||
ret = self._test_list_resources(resources, cmd,
|
||||
response_contents=contents)
|
||||
ret_words = set(ret.split())
|
||||
# Check only the default columns are shown.
|
||||
self.assertTrue('name' in ret_words)
|
||||
self.assertTrue('alias' in ret_words)
|
||||
self.assertFalse('other' in ret_words)
|
||||
|
||||
def test_show_extension(self):
|
||||
# -F option does not work for ext-show at the moment, so -F option
|
||||
# is not passed in the commandline args as other tests do.
|
||||
resource = 'extension'
|
||||
cmd = ShowExt(MyApp(sys.stdout), None)
|
||||
args = [self.test_id]
|
||||
ext_alias = self.test_id
|
||||
self._test_show_resource(resource, cmd, ext_alias, args, fields=[])
|
Loading…
Reference in New Issue