Display subnet cidr information in net-list
Fixes bug 1074415 This commit introduces extend_list() in ListCommand class. This method can be used to update a retrieved list (e.g., add additional information or convert some field to more human-readable value). Change-Id: Icf5ab616ab4d9add16c921e1944ba37b376b2ab2
This commit is contained in:
parent
093bac1bc6
commit
ab5399e64d
quantumclient
@ -341,7 +341,7 @@ class DeleteCommand(QuantumCommand):
|
||||
|
||||
|
||||
class ListCommand(QuantumCommand, lister.Lister):
|
||||
"""List resourcs that belong to a given tenant
|
||||
"""List resources that belong to a given tenant
|
||||
|
||||
"""
|
||||
|
||||
@ -357,11 +357,10 @@ class ListCommand(QuantumCommand, lister.Lister):
|
||||
add_extra_argument(parser, 'filter_specs', 'filters options')
|
||||
return parser
|
||||
|
||||
def get_data(self, parsed_args):
|
||||
self.log.debug('get_data(%s)' % parsed_args)
|
||||
def retrieve_list(self, parsed_args):
|
||||
"""Retrieve a list of resources from Quantum server"""
|
||||
quantum_client = self.get_client()
|
||||
search_opts = parse_args_to_dict(parsed_args.filter_specs)
|
||||
|
||||
self.log.debug('search options: %s', search_opts)
|
||||
quantum_client.format = parsed_args.request_format
|
||||
fields = parsed_args.fields
|
||||
@ -377,12 +376,21 @@ class ListCommand(QuantumCommand, lister.Lister):
|
||||
search_opts.update({'verbose': 'True'})
|
||||
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]
|
||||
return data.get(collection, [])
|
||||
|
||||
def extend_list(self, data, parsed_args):
|
||||
"""Update a retrieved list.
|
||||
|
||||
This method provides a way to modify a original list returned from
|
||||
the quantum server. For example, you can add subnet cidr information
|
||||
to a list network.
|
||||
"""
|
||||
pass
|
||||
|
||||
def setup_columns(self, info, parsed_args):
|
||||
_columns = len(info) > 0 and sorted(info[0].keys()) or []
|
||||
if not _columns:
|
||||
# clean the parsed_args.columns so that cliff will not break
|
||||
@ -398,6 +406,12 @@ class ListCommand(QuantumCommand, lister.Lister):
|
||||
s, _columns, formatters=self._formatters, )
|
||||
for s in info), )
|
||||
|
||||
def get_data(self, parsed_args):
|
||||
self.log.debug('get_data(%s)' % parsed_args)
|
||||
data = self.retrieve_list(parsed_args)
|
||||
self.extend_list(data, parsed_args)
|
||||
return self.setup_columns(data, parsed_args)
|
||||
|
||||
|
||||
class ShowCommand(QuantumCommand, show.ShowOne):
|
||||
"""Show information of a given resource
|
||||
|
@ -18,6 +18,7 @@
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
from quantumclient.common import utils
|
||||
from quantumclient.quantum.v2_0 import CreateCommand
|
||||
from quantumclient.quantum.v2_0 import DeleteCommand
|
||||
from quantumclient.quantum.v2_0 import ListCommand
|
||||
@ -27,7 +28,8 @@ from quantumclient.quantum.v2_0 import UpdateCommand
|
||||
|
||||
def _format_subnets(network):
|
||||
try:
|
||||
return '\n'.join(network['subnets'])
|
||||
return '\n'.join([' '.join([s['id'], s.get('cidr', '')])
|
||||
for s in network['subnets']])
|
||||
except Exception:
|
||||
return ''
|
||||
|
||||
@ -40,20 +42,28 @@ class ListNetwork(ListCommand):
|
||||
_formatters = {'subnets': _format_subnets, }
|
||||
list_columns = ['id', 'name', 'subnets']
|
||||
|
||||
def extend_list(self, data, parsed_args):
|
||||
"""Add subnet information to a network list"""
|
||||
quantum_client = self.get_client()
|
||||
search_opts = {'fields': ['id', 'cidr']}
|
||||
subnets = quantum_client.list_subnets(**search_opts).get('subnets', [])
|
||||
subnet_dict = dict([(s['id'], s) for s in subnets])
|
||||
for n in data:
|
||||
if 'subnets' in n:
|
||||
n['subnets'] = [(subnet_dict.get(s) or {"id": s})
|
||||
for s in n['subnets']]
|
||||
|
||||
class ListExternalNetwork(ListCommand):
|
||||
|
||||
class ListExternalNetwork(ListNetwork):
|
||||
"""List external networks that belong to a given tenant"""
|
||||
|
||||
resource = 'network'
|
||||
log = logging.getLogger(__name__ + '.ListExternalNetwork')
|
||||
_formatters = {'subnets': _format_subnets, }
|
||||
list_colums = ['id', 'name', 'subnets']
|
||||
|
||||
def get_data(self, parsed_args):
|
||||
def retrieve_list(self, parsed_args):
|
||||
if '--' not in parsed_args.filter_specs:
|
||||
parsed_args.filter_specs.append('--')
|
||||
parsed_args.filter_specs.append('--router:external=True')
|
||||
return super(ListExternalNetwork, self).get_data(parsed_args)
|
||||
return super(ListExternalNetwork, self).retrieve_list(parsed_args)
|
||||
|
||||
|
||||
class ShowNetwork(ShowCommand):
|
||||
|
@ -17,7 +17,8 @@
|
||||
|
||||
import sys
|
||||
|
||||
from mox import ContainsKeyValue
|
||||
import mox
|
||||
from mox import (ContainsKeyValue, IgnoreArg, IsA)
|
||||
|
||||
from quantumclient.common import exceptions
|
||||
from quantumclient.common import utils
|
||||
@ -101,6 +102,8 @@ class CLITestV20Network(CLITestV20Base):
|
||||
cmd = ListNetwork(MyApp(sys.stdout), None)
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
self.mox.StubOutWithMock(ListNetwork, "extend_list")
|
||||
ListNetwork.extend_list(IsA(list), IgnoreArg())
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
reses = {resources: []}
|
||||
resstr = self.client.serialize(reses)
|
||||
@ -125,40 +128,109 @@ class CLITestV20Network(CLITestV20Base):
|
||||
_str = self.fake_stdout.make_string()
|
||||
self.assertEquals('\n', _str)
|
||||
|
||||
def _test_list_networks(self, cmd, detail=False, tags=[],
|
||||
fields_1=[], fields_2=[]):
|
||||
resources = "networks"
|
||||
self.mox.StubOutWithMock(ListNetwork, "extend_list")
|
||||
ListNetwork.extend_list(IsA(list), IgnoreArg())
|
||||
self._test_list_resources(resources, cmd, detail, tags,
|
||||
fields_1, fields_2)
|
||||
|
||||
def test_list_nets_detail(self):
|
||||
"""list nets: -D."""
|
||||
resources = "networks"
|
||||
cmd = ListNetwork(MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
self._test_list_networks(cmd, True)
|
||||
|
||||
def test_list_nets_tags(self):
|
||||
"""List nets: -- --tags a b."""
|
||||
resources = "networks"
|
||||
cmd = ListNetwork(MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, tags=['a', 'b'])
|
||||
self._test_list_networks(cmd, tags=['a', 'b'])
|
||||
|
||||
def test_list_nets_detail_tags(self):
|
||||
"""List nets: -D -- --tags a b."""
|
||||
resources = "networks"
|
||||
cmd = ListNetwork(MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, detail=True, tags=['a', 'b'])
|
||||
self._test_list_networks(cmd, detail=True, tags=['a', 'b'])
|
||||
|
||||
def _test_list_nets_extend_subnets(self, data, expected):
|
||||
def setup_list_stub(resources, data, query):
|
||||
reses = {resources: data}
|
||||
resstr = self.client.serialize(reses)
|
||||
resp = (test_cli20.MyResp(200), resstr)
|
||||
path = getattr(self.client, resources + '_path')
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path, query), 'GET',
|
||||
body=None,
|
||||
headers=ContainsKeyValue(
|
||||
'X-Auth-Token', test_cli20.TOKEN)).AndReturn(resp)
|
||||
|
||||
resources = "networks"
|
||||
cmd = ListNetwork(test_cli20.MyApp(sys.stdout), None)
|
||||
self.mox.StubOutWithMock(cmd, 'get_client')
|
||||
self.mox.StubOutWithMock(self.client.httpclient, 'request')
|
||||
cmd.get_client().AndReturn(self.client)
|
||||
setup_list_stub('networks', data, '')
|
||||
cmd.get_client().AndReturn(self.client)
|
||||
setup_list_stub('subnets',
|
||||
[{'id': 'mysubid1', 'cidr': '192.168.1.0/24'},
|
||||
{'id': 'mysubid2', 'cidr': '172.16.0.0/24'},
|
||||
{'id': 'mysubid3', 'cidr': '10.1.1.0/24'}],
|
||||
query='fields=id&fields=cidr')
|
||||
self.mox.ReplayAll()
|
||||
|
||||
args = []
|
||||
cmd_parser = cmd.get_parser('list_networks')
|
||||
parsed_args = cmd_parser.parse_args(args)
|
||||
result = cmd.get_data(parsed_args)
|
||||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
_result = [x for x in result[1]]
|
||||
self.assertEqual(len(_result), len(expected))
|
||||
for res, exp in zip(_result, expected):
|
||||
self.assertEqual(len(res), len(exp))
|
||||
for a, b in zip(res, exp):
|
||||
self.assertEqual(a, b)
|
||||
|
||||
def test_list_nets_extend_subnets(self):
|
||||
data = [{'id': 'netid1', 'name': 'net1', 'subnets': ['mysubid1']},
|
||||
{'id': 'netid2', 'name': 'net2', 'subnets': ['mysubid2',
|
||||
'mysubid3']}]
|
||||
# id, name, subnets
|
||||
expected = [('netid1', 'net1', 'mysubid1 192.168.1.0/24'),
|
||||
('netid2', 'net2',
|
||||
'mysubid2 172.16.0.0/24\nmysubid3 10.1.1.0/24')]
|
||||
self._test_list_nets_extend_subnets(data, expected)
|
||||
|
||||
def test_list_nets_extend_subnets_no_subnet(self):
|
||||
data = [{'id': 'netid1', 'name': 'net1', 'subnets': ['mysubid1']},
|
||||
{'id': 'netid2', 'name': 'net2', 'subnets': ['mysubid4']}]
|
||||
# id, name, subnets
|
||||
expected = [('netid1', 'net1', 'mysubid1 192.168.1.0/24'),
|
||||
('netid2', 'net2', 'mysubid4 ')]
|
||||
self._test_list_nets_extend_subnets(data, expected)
|
||||
|
||||
def test_list_nets_fields(self):
|
||||
"""List nets: --fields a --fields b -- --fields c d."""
|
||||
resources = "networks"
|
||||
cmd = ListNetwork(MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
fields_1=['a', 'b'], fields_2=['c', 'd'])
|
||||
self._test_list_networks(cmd,
|
||||
fields_1=['a', 'b'], fields_2=['c', 'd'])
|
||||
|
||||
def _test_list_nets_columns(self, cmd, returned_body,
|
||||
args=['-f', 'json']):
|
||||
resources = 'networks'
|
||||
self.mox.StubOutWithMock(ListNetwork, "extend_list")
|
||||
ListNetwork.extend_list(IsA(list), IgnoreArg())
|
||||
self._test_list_columns(cmd, resources, returned_body, args=args)
|
||||
|
||||
def test_list_nets_defined_column(self):
|
||||
resources = 'networks'
|
||||
cmd = ListNetwork(MyApp(sys.stdout), None)
|
||||
returned_body = {"networks": [{"name": "buildname3",
|
||||
"id": "id3",
|
||||
"tenant_id": "tenant_3",
|
||||
"subnets": []}]}
|
||||
self._test_list_columns(cmd, resources, returned_body,
|
||||
args=['-f', 'json', '-c', 'id'])
|
||||
self._test_list_nets_columns(cmd, returned_body,
|
||||
args=['-f', 'json', '-c', 'id'])
|
||||
_str = self.fake_stdout.make_string()
|
||||
returned_networks = utils.loads(_str)
|
||||
self.assertEquals(1, len(returned_networks))
|
||||
@ -167,13 +239,12 @@ class CLITestV20Network(CLITestV20Base):
|
||||
self.assertEquals("id", network.keys()[0])
|
||||
|
||||
def test_list_nets_with_default_column(self):
|
||||
resources = 'networks'
|
||||
cmd = ListNetwork(MyApp(sys.stdout), None)
|
||||
returned_body = {"networks": [{"name": "buildname3",
|
||||
"id": "id3",
|
||||
"tenant_id": "tenant_3",
|
||||
"subnets": []}]}
|
||||
self._test_list_columns(cmd, resources, returned_body)
|
||||
self._test_list_nets_columns(cmd, returned_body)
|
||||
_str = self.fake_stdout.make_string()
|
||||
returned_networks = utils.loads(_str)
|
||||
self.assertEquals(1, len(returned_networks))
|
||||
@ -187,6 +258,8 @@ class CLITestV20Network(CLITestV20Base):
|
||||
cmd = ListExternalNetwork(MyApp(sys.stdout), None)
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
self.mox.StubOutWithMock(ListNetwork, "extend_list")
|
||||
ListNetwork.extend_list(IsA(list), IgnoreArg())
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
reses = {resources: []}
|
||||
resstr = self.client.serialize(reses)
|
||||
@ -217,6 +290,8 @@ class CLITestV20Network(CLITestV20Base):
|
||||
fields_1=[], fields_2=[]):
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
self.mox.StubOutWithMock(ListNetwork, "extend_list")
|
||||
ListNetwork.extend_list(IsA(list), IgnoreArg())
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
reses = {resources: [{'id': 'myid1', },
|
||||
{'id': 'myid2', }, ], }
|
||||
|
Loading…
x
Reference in New Issue
Block a user