Add extra filtering options to floating ip list

The patch adds filtering '--long', 'status', '--project',
'--project-domain' and '--router' options to
floating ip list command.

Closes-Bug: #1614379
Partially-Implements: blueprint network-commands-options
Change-Id: I2a02cf23845ff435927d8b481f77249915bd94dc
This commit is contained in:
songminglong 2016-12-09 14:23:26 +08:00
parent 83cf09df28
commit 47716d1ad3
4 changed files with 207 additions and 0 deletions

View File

@ -89,6 +89,10 @@ List floating IP(s)
[--network <network>]
[--port <port>]
[--fixed-ip-address <fixed-ip-address>]
[--long]
[--status <status>]
[--project <project> [--project-domain <project-domain>]]
[--router <router>]
.. option:: --network <network>
@ -108,6 +112,37 @@ List floating IP(s)
*Network version 2 only*
.. option:: --long
List additional fields in output
*Network version 2 only*
.. option:: --status <status>
List floating IP(s) according to given status ('ACTIVE', 'DOWN')
*Network version 2 only*
.. option:: --project <project>
List floating IP(s) according to given project (name or ID)
*Network version 2 only*
.. option:: --project-domain <project-domain>
Domain the project belongs to (name or ID). This can
be used in case collisions between project names exist.
*Network version 2 only*
.. option:: --router <router>
List floating IP(s) according to given router (name or ID)
*Network version 2 only*
floating ip show
----------------

View File

@ -219,6 +219,8 @@ class DeleteIPFloating(DeleteFloatingIP):
class ListFloatingIP(common.NetworkAndComputeLister):
# TODO(songminglong): Use SDK resource mapped attribute names once
# the OSC minimum requirements include SDK 1.0
_description = _("List floating IP(s)")
def update_parser_network(self, parser):
@ -240,11 +242,38 @@ class ListFloatingIP(common.NetworkAndComputeLister):
help=_("List floating IP(s) according to "
"given fixed IP address")
)
parser.add_argument(
'--long',
action='store_true',
default=False,
help=_("List additional fields in output")
)
parser.add_argument(
'--status',
metavar='<status>',
choices=['ACTIVE', 'DOWN'],
help=_("List floating IP(s) according to "
"given status ('ACTIVE', 'DOWN')")
)
parser.add_argument(
'--project',
metavar='<project>',
help=_("List floating IP(s) according to "
"given project (name or ID)")
)
identity_common.add_project_domain_option_to_parser(parser)
parser.add_argument(
'--router',
metavar='<router>',
help=_("List floating IP(s) according to "
"given router (name or ID)")
)
return parser
def take_action_network(self, client, parsed_args):
network_client = self.app.client_manager.network
identity_client = self.app.client_manager.identity
columns = (
'id',
@ -262,6 +291,17 @@ class ListFloatingIP(common.NetworkAndComputeLister):
'Floating Network',
'Project',
)
if parsed_args.long:
columns = columns + (
'router_id',
'status',
'description',
)
headers = headers + (
'Router',
'Status',
'Description',
)
query = {}
@ -275,6 +315,20 @@ class ListFloatingIP(common.NetworkAndComputeLister):
query['port_id'] = port.id
if parsed_args.fixed_ip_address is not None:
query['fixed_ip_address'] = parsed_args.fixed_ip_address
if parsed_args.status:
query['status'] = parsed_args.status
if parsed_args.project is not None:
project = identity_common.find_project(
identity_client,
parsed_args.project,
parsed_args.project_domain,
)
query['tenant_id'] = project.id
query['project_id'] = project.id
if parsed_args.router is not None:
router = network_client.find_router(parsed_args.router,
ignore_missing=False)
query['router_id'] = router.id
data = client.ips(**query)

View File

@ -32,7 +32,10 @@ class TestFloatingIPNetwork(network_fakes.TestNetworkV2):
# Get a shortcut to the network client
self.network = self.app.client_manager.network
# Get a shortcut to the ProjectManager Mock
self.projects_mock = self.app.client_manager.identity.projects
# Get a shortcut to the DomainManager Mock
self.domains_mock = self.app.client_manager.identity.domains
class TestCreateFloatingIPNetwork(TestFloatingIPNetwork):
@ -287,6 +290,9 @@ class TestListFloatingIPNetwork(TestFloatingIPNetwork):
fake_port = network_fakes.FakePort.create_one_port({
'id': 'fake_port_id',
})
fake_router = network_fakes.FakeRouter.create_one_router({
'id': 'fake_router_id',
})
columns = (
'ID',
@ -296,8 +302,14 @@ class TestListFloatingIPNetwork(TestFloatingIPNetwork):
'Floating Network',
'Project',
)
columns_long = columns + (
'Router',
'Status',
'Description',
)
data = []
data_long = []
for ip in floating_ips:
data.append((
ip.id,
@ -307,6 +319,17 @@ class TestListFloatingIPNetwork(TestFloatingIPNetwork):
ip.floating_network_id,
ip.tenant_id,
))
data_long.append((
ip.id,
ip.floating_ip_address,
ip.fixed_ip_address,
ip.port_id,
ip.floating_network_id,
ip.tenant_id,
ip.router_id,
ip.status,
ip.description,
))
def setUp(self):
super(TestListFloatingIPNetwork, self).setUp()
@ -314,6 +337,7 @@ class TestListFloatingIPNetwork(TestFloatingIPNetwork):
self.network.ips = mock.Mock(return_value=self.floating_ips)
self.network.find_network = mock.Mock(return_value=self.fake_network)
self.network.find_port = mock.Mock(return_value=self.fake_port)
self.network.find_router = mock.Mock(return_value=self.fake_router)
# Get the command object to test
self.cmd = floating_ip.ListFloatingIP(self.app, self.namespace)
@ -380,6 +404,94 @@ class TestListFloatingIPNetwork(TestFloatingIPNetwork):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_floating_ip_list_long(self):
arglist = ['--long', ]
verifylist = [('long', True), ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.network.ips.assert_called_once_with()
self.assertEqual(self.columns_long, columns)
self.assertEqual(self.data_long, list(data))
def test_floating_ip_list_status(self):
arglist = [
'--status', 'ACTIVE',
'--long',
]
verifylist = [
('status', 'ACTIVE'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.network.ips.assert_called_once_with(**{
'status': 'ACTIVE',
})
self.assertEqual(self.columns_long, columns)
self.assertEqual(self.data_long, list(data))
def test_floating_ip_list_project(self):
project = identity_fakes_v3.FakeProject.create_one_project()
self.projects_mock.get.return_value = project
arglist = [
'--project', project.id,
]
verifylist = [
('project', project.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
filters = {'tenant_id': project.id,
'project_id': project.id, }
self.network.ips.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_floating_ip_list_project_domain(self):
project = identity_fakes_v3.FakeProject.create_one_project()
self.projects_mock.get.return_value = project
arglist = [
'--project', project.id,
'--project-domain', project.domain_id,
]
verifylist = [
('project', project.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
filters = {'tenant_id': project.id,
'project_id': project.id, }
self.network.ips.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_floating_ip_list_router(self):
arglist = [
'--router', 'fake_router_id',
'--long',
]
verifylist = [
('router', 'fake_router_id'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.network.ips.assert_called_once_with(**{
'router_id': 'fake_router_id',
})
self.assertEqual(self.columns_long, columns)
self.assertEqual(self.data_long, list(data))
class TestShowFloatingIPNetwork(TestFloatingIPNetwork):

View File

@ -0,0 +1,6 @@
---
features:
- |
Add ``--long``, ``--status``, ``--project``, ``--project-domain``,
and ``--router`` options to ``floating ip list`` command.
[Bug `1614379 <https://bugs.launchpad.net/bugs/1614379>`_]