Skip to content

Commit

Permalink
Convenience cmds for l3
Browse files Browse the repository at this point in the history
Bug #1049551

Add two CLI and unit tests:
quantum net-external-list
(runs net-list with router:external=True filter)
quantum router-port-list <router-id/name>
(runs port-list, filtering with device_id equal to specified router)

Change-Id: I9a9668836ac24d4cbc6a3867ec031611b64ded14
  • Loading branch information
ivan-zhu committed Nov 13, 2012
1 parent 3e19fc0 commit eb7a744
Show file tree
Hide file tree
Showing 5 changed files with 302 additions and 33 deletions.
15 changes: 15 additions & 0 deletions quantumclient/quantum/v2_0/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ class ListNetwork(ListCommand):
list_columns = ['id', 'name', 'subnets']


class ListExternalNetwork(ListCommand):
"""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):
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)


class ShowNetwork(ShowCommand):
"""Show information of a given network."""

Expand Down
29 changes: 28 additions & 1 deletion quantumclient/quantum/v2_0/port.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,41 @@ def _format_fixed_ips(port):


class ListPort(ListCommand):
"""List networks that belong to a given tenant."""
"""List ports that belong to a given tenant."""

resource = 'port'
log = logging.getLogger(__name__ + '.ListPort')
_formatters = {'fixed_ips': _format_fixed_ips, }
list_columns = ['id', 'name', 'mac_address', 'fixed_ips']


class ListRouterPort(ListCommand):
"""List ports that belong to a given tenant, with specified router"""

resource = 'port'
log = logging.getLogger(__name__ + '.ListRouterPort')
_formatters = {'fixed_ips': _format_fixed_ips, }
list_columns = ['id', 'name', 'mac_address', 'fixed_ips']

def get_parser(self, prog_name):
parser = super(ListCommand, self).get_parser(prog_name)
quantumv20.add_show_list_common_argument(parser)
parser.add_argument(
'id', metavar='router',
help='ID or name of router to look up')
quantumv20.add_extra_argument(parser, 'filter_specs',
'filters options')
return parser

def get_data(self, parsed_args):
quantum_client = self.get_client()
quantum_client.format = parsed_args.request_format
_id = quantumv20.find_resourceid_by_name_or_id(
quantum_client, 'router', parsed_args.id)
parsed_args.filter_specs.append('--device_id=%s' % _id)
return super(ListRouterPort, self).get_data(parsed_args)


class ShowPort(ShowCommand):
"""Show information of a given port."""

Expand Down
4 changes: 4 additions & 0 deletions quantumclient/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ def env(*_vars, **kwargs):
COMMAND_V2 = {
'net-list': utils.import_class(
'quantumclient.quantum.v2_0.network.ListNetwork'),
'net-external-list': utils.import_class(
'quantumclient.quantum.v2_0.network.ListExternalNetwork'),
'net-show': utils.import_class(
'quantumclient.quantum.v2_0.network.ShowNetwork'),
'net-create': utils.import_class(
Expand Down Expand Up @@ -96,6 +98,8 @@ def env(*_vars, **kwargs):
'quantumclient.quantum.v2_0.extension.ShowExt'),
'router-list': utils.import_class(
'quantumclient.quantum.v2_0.router.ListRouter'),
'router-port-list': utils.import_class(
'quantumclient.quantum.v2_0.port.ListRouterPort'),
'router-show': utils.import_class(
'quantumclient.quantum.v2_0.router.ShowRouter'),
'router-create': utils.import_class(
Expand Down
160 changes: 143 additions & 17 deletions quantumclient/tests/unit/test_cli20_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4

import sys
from mox import ContainsKeyValue

from quantumclient.common import exceptions
from quantumclient.common import utils
Expand All @@ -27,6 +28,7 @@
from quantumclient.quantum.v2_0.network import UpdateNetwork
from quantumclient.quantum.v2_0.network import ShowNetwork
from quantumclient.quantum.v2_0.network import DeleteNetwork
from quantumclient.quantum.v2_0.network import ListExternalNetwork


class CLITestV20Network(CLITestV20Base):
Expand All @@ -39,8 +41,8 @@ def test_create_network(self):
args = [name, ]
position_names = ['name', ]
position_values = [name, ]
_str = self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values)
self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values)

def test_create_network_tenant(self):
"""Create net: --tenant_id tenantid myname."""
Expand All @@ -51,15 +53,15 @@ def test_create_network_tenant(self):
args = ['--tenant_id', 'tenantid', name]
position_names = ['name', ]
position_values = [name, ]
_str = self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values,
tenant_id='tenantid')
self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values,
tenant_id='tenantid')

# Test dashed options
args = ['--tenant-id', 'tenantid', name]
_str = self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values,
tenant_id='tenantid')
self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values,
tenant_id='tenantid')

def test_create_network_tags(self):
"""Create net: myname --tags a b."""
Expand All @@ -70,9 +72,9 @@ def test_create_network_tags(self):
args = [name, '--tags', 'a', 'b']
position_names = ['name', ]
position_values = [name, ]
_str = self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values,
tags=['a', 'b'])
self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values,
tags=['a', 'b'])

def test_create_network_state(self):
"""Create net: --admin_state_down myname."""
Expand All @@ -83,15 +85,15 @@ def test_create_network_state(self):
args = ['--admin_state_down', name, ]
position_names = ['name', ]
position_values = [name, ]
_str = self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values,
admin_state_up=False)
self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values,
admin_state_up=False)

# Test dashed options
args = ['--admin-state-down', name, ]
_str = self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values,
admin_state_up=False)
self._test_create_resource(resource, cmd, name, myid, args,
position_names, position_values,
admin_state_up=False)

def test_list_nets_empty_with_column(self):
resources = "networks"
Expand Down Expand Up @@ -179,6 +181,130 @@ def test_list_nets_with_default_column(self):
self.assertEquals(0, len(set(network) ^
set(cmd.list_columns)))

def test_list_external_nets_empty_with_column(self):
resources = "networks"
cmd = ListExternalNetwork(MyApp(sys.stdout), None)
self.mox.StubOutWithMock(cmd, "get_client")
self.mox.StubOutWithMock(self.client.httpclient, "request")
cmd.get_client().MultipleTimes().AndReturn(self.client)
reses = {resources: []}
resstr = self.client.serialize(reses)
# url method body
query = "router%3Aexternal=True&id=myfakeid"
args = ['-c', 'id', '--', '--id', 'myfakeid']
path = getattr(self.client, resources + "_path")
self.client.httpclient.request(
test_cli20.end_url(path, query), 'GET',
body=None,
headers=test_cli20.ContainsKeyValue(
'X-Auth-Token',
test_cli20.TOKEN)).AndReturn(
(test_cli20.MyResp(200), resstr))
self.mox.ReplayAll()
cmd_parser = cmd.get_parser("list_" + resources)

parsed_args = cmd_parser.parse_args(args)

cmd.run(parsed_args)
self.mox.VerifyAll()
self.mox.UnsetStubs()
_str = self.fake_stdout.make_string()
self.assertEquals('\n', _str)

def _test_list_external_nets(self, resources, cmd,
detail=False, tags=[],
fields_1=[], fields_2=[]):
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', }, ], }

resstr = self.client.serialize(reses)

# url method body
query = ""
args = detail and ['-D', ] or []
if fields_1:
for field in fields_1:
args.append('--fields')
args.append(field)
if tags:
args.append('--')
args.append("--tag")
for tag in tags:
args.append(tag)
if (not tags) and fields_2:
args.append('--')
if fields_2:
args.append("--fields")
for field in fields_2:
args.append(field)
fields_1.extend(fields_2)
for field in fields_1:
if query:
query += "&fields=" + field
else:
query = "fields=" + field
if query:
query += '&router%3Aexternal=True'
else:
query += 'router%3Aexternal=True'
for tag in tags:
if query:
query += "&tag=" + tag
else:
query = "tag=" + tag
if detail:
query = query and query + '&verbose=True' or 'verbose=True'
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(
(test_cli20.MyResp(200), resstr))
self.mox.ReplayAll()
cmd_parser = cmd.get_parser("list_" + resources)

parsed_args = cmd_parser.parse_args(args)
cmd.run(parsed_args)

self.mox.VerifyAll()
self.mox.UnsetStubs()
_str = self.fake_stdout.make_string()

self.assertTrue('myid1' in _str)

def test_list_external_nets_detail(self):
"""list external nets: -D."""
resources = "networks"
cmd = ListExternalNetwork(MyApp(sys.stdout), None)
self._test_list_external_nets(resources, cmd, True)

def test_list_external_nets_tags(self):
"""List external nets: -- --tags a b."""
resources = "networks"
cmd = ListExternalNetwork(MyApp(sys.stdout), None)
self._test_list_external_nets(resources,
cmd, tags=['a', 'b'])

def test_list_external_nets_detail_tags(self):
"""List external nets: -D -- --tags a b."""
resources = "networks"
cmd = ListExternalNetwork(MyApp(sys.stdout), None)
self._test_list_external_nets(resources, cmd,
detail=True, tags=['a', 'b'])

def test_list_externel_nets_fields(self):
"""List external nets: --fields a --fields b -- --fields c d."""
resources = "networks"
cmd = ListExternalNetwork(MyApp(sys.stdout), None)
self._test_list_external_nets(resources, cmd,
fields_1=['a', 'b'],
fields_2=['c', 'd'])

def test_update_network_exception(self):
"""Update net: myid."""
resource = 'network'
Expand Down

0 comments on commit eb7a744

Please sign in to comment.