From 62a02466c30e32f8eb54a70497eacacb7fa5c9bf Mon Sep 17 00:00:00 2001
From: Jas <singhj@us.ibm.com>
Date: Fri, 11 Mar 2016 13:02:47 -0600
Subject: [PATCH] Add option to allow filtering by router on port list

Added support to allow filtering ports via --router
option to list ports that are applicable to specific router.

Partial-bug: #1519909
Partially-implements: blueprint neutron-client

Change-Id: I6dd958603909f641735c821a62fc0d45afd5c7ec
---
 doc/source/command-objects/port.rst           |  5 ++++
 openstackclient/network/v2/port.py            | 19 ++++++++++++++-
 openstackclient/tests/network/v2/test_port.py | 24 ++++++++++++++++++-
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/doc/source/command-objects/port.rst b/doc/source/command-objects/port.rst
index e9c091736a..1910716294 100644
--- a/doc/source/command-objects/port.rst
+++ b/doc/source/command-objects/port.rst
@@ -108,6 +108,11 @@ List ports
 .. code:: bash
 
     os port list
+        [--router <router>]
+
+.. option:: --router <router>
+
+    List only ports attached to this router (name or ID)
 
 port set
 --------
diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py
index b618a4b0c7..9894e6da62 100644
--- a/openstackclient/network/v2/port.py
+++ b/openstackclient/network/v2/port.py
@@ -243,6 +243,16 @@ class DeletePort(command.Command):
 class ListPort(command.Lister):
     """List ports"""
 
+    def get_parser(self, prog_name):
+        parser = super(ListPort, self).get_parser(prog_name)
+        parser.add_argument(
+            '--router',
+            metavar='<router>',
+            dest='router',
+            help='List only ports attached to this router (name or ID)',
+        )
+        return parser
+
     def take_action(self, parsed_args):
         client = self.app.client_manager.network
 
@@ -259,7 +269,14 @@ class ListPort(command.Lister):
             'Fixed IP Addresses',
         )
 
-        data = client.ports()
+        filters = {}
+        if parsed_args.router:
+            _router = client.find_router(parsed_args.router,
+                                         ignore_missing=False)
+            filters = {'device_id': _router.id}
+
+        data = client.ports(**filters)
+
         return (column_headers,
                 (utils.get_item_properties(
                     s, columns,
diff --git a/openstackclient/tests/network/v2/test_port.py b/openstackclient/tests/network/v2/test_port.py
index 7b1c655f67..54f8285333 100644
--- a/openstackclient/tests/network/v2/test_port.py
+++ b/openstackclient/tests/network/v2/test_port.py
@@ -224,8 +224,11 @@ class TestListPort(TestPort):
 
         # Get the command object to test
         self.cmd = port.ListPort(self.app, self.namespace)
-
         self.network.ports = mock.Mock(return_value=self._ports)
+        fake_router = network_fakes.FakeRouter.create_one_router({
+            'id': 'fake-router-id',
+        })
+        self.network.find_router = mock.Mock(return_value=fake_router)
 
     def test_port_list_no_options(self):
         arglist = []
@@ -239,6 +242,25 @@ class TestListPort(TestPort):
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
 
+    def test_port_list_router_opt(self):
+        arglist = [
+            '--router', 'fake-router-name',
+        ]
+
+        verifylist = [
+            ('router', 'fake-router-name')
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.network.ports.assert_called_with(**{
+            'device_id': 'fake-router-id'
+        })
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, list(data))
+
 
 class TestSetPort(TestPort):