From aa5ff67e3fa2b9497218e9bdd4ac3fdf432e007c Mon Sep 17 00:00:00 2001
From: Huanxuan Ao <huanxuan.ao@easystack.cn>
Date: Sat, 7 May 2016 16:15:53 +0800
Subject: [PATCH] Implement "address scope list" command

This patch add a command that supports
listing address scopes

Change-Id: Id14757011560cacf28011ba51841a8e23b824f33
Partial-Bug: #1566269
---
 doc/source/command-objects/address-scope.rst  | 10 +++++
 openstackclient/network/v2/address_scope.py   | 27 ++++++++++++
 openstackclient/tests/network/v2/fakes.py     | 18 ++++++++
 .../tests/network/v2/test_address_scope.py    | 42 +++++++++++++++++++
 setup.cfg                                     |  1 +
 5 files changed, 98 insertions(+)

diff --git a/doc/source/command-objects/address-scope.rst b/doc/source/command-objects/address-scope.rst
index 2f922353b0..2c701a4941 100644
--- a/doc/source/command-objects/address-scope.rst
+++ b/doc/source/command-objects/address-scope.rst
@@ -62,3 +62,13 @@ Delete an address scope
 .. describe:: <address-scope>
 
     Address scope to delete (name or ID)
+
+address scope list
+------------------
+
+List address scopes
+
+.. program:: address scope list
+.. code:: bash
+
+    os address scope list
diff --git a/openstackclient/network/v2/address_scope.py b/openstackclient/network/v2/address_scope.py
index 361fd3600a..dd43ef5b21 100644
--- a/openstackclient/network/v2/address_scope.py
+++ b/openstackclient/network/v2/address_scope.py
@@ -113,3 +113,30 @@ class DeleteAddressScope(command.Command):
         client = self.app.client_manager.network
         obj = client.find_address_scope(parsed_args.address_scope)
         client.delete_address_scope(obj)
+
+
+class ListAddressScope(command.Lister):
+    """List address scopes"""
+
+    def take_action(self, parsed_args):
+        client = self.app.client_manager.network
+        columns = (
+            'id',
+            'name',
+            'ip_version',
+            'shared',
+            'tenant_id',
+        )
+        column_headers = (
+            'ID',
+            'Name',
+            'IP Version',
+            'Shared',
+            'Project',
+        )
+        data = client.address_scopes()
+
+        return (column_headers,
+                (utils.get_item_properties(
+                    s, columns, formatters={},
+                ) for s in data))
diff --git a/openstackclient/tests/network/v2/fakes.py b/openstackclient/tests/network/v2/fakes.py
index 5fd7ea3b86..413ec7d2c5 100644
--- a/openstackclient/tests/network/v2/fakes.py
+++ b/openstackclient/tests/network/v2/fakes.py
@@ -107,6 +107,24 @@ class FakeAddressScope(object):
 
         return address_scope
 
+    @staticmethod
+    def create_address_scopes(attrs=None, count=2):
+        """Create multiple fake address scopes.
+
+        :param Dictionary attrs:
+            A dictionary with all attributes
+        :param int count:
+            The number of address scopes to fake
+        :return:
+            A list of FakeResource objects faking the address scopes
+        """
+        address_scopes = []
+        for i in range(0, count):
+            address_scopes.append(
+                FakeAddressScope.create_one_address_scope(attrs))
+
+        return address_scopes
+
 
 class FakeAvailabilityZone(object):
     """Fake one or more network availability zones (AZs)."""
diff --git a/openstackclient/tests/network/v2/test_address_scope.py b/openstackclient/tests/network/v2/test_address_scope.py
index 3168ea3f6f..d33013ce9a 100644
--- a/openstackclient/tests/network/v2/test_address_scope.py
+++ b/openstackclient/tests/network/v2/test_address_scope.py
@@ -193,3 +193,45 @@ class TestDeleteAddressScope(TestAddressScope):
         self.network.delete_address_scope.assert_called_once_with(
             self._address_scope)
         self.assertIsNone(result)
+
+
+class TestListAddressScope(TestAddressScope):
+
+    # The address scopes to list up.
+    address_scopes = (
+        network_fakes.FakeAddressScope.create_address_scopes(count=3))
+    columns = (
+        'ID',
+        'Name',
+        'IP Version',
+        'Shared',
+        'Project',
+    )
+    data = []
+    for scope in address_scopes:
+        data.append((
+            scope.id,
+            scope.name,
+            scope.ip_version,
+            scope.shared,
+            scope.project_id,
+        ))
+
+    def setUp(self):
+        super(TestListAddressScope, self).setUp()
+        self.network.address_scopes = mock.Mock(
+            return_value=self.address_scopes)
+
+        # Get the command object to test
+        self.cmd = address_scope.ListAddressScope(self.app, self.namespace)
+
+    def test_address_scope_list(self):
+        arglist = []
+        verifylist = []
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.network.address_scopes.assert_called_once_with(**{})
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, list(data))
diff --git a/setup.cfg b/setup.cfg
index ae9842301b..18f177dc48 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -321,6 +321,7 @@ openstack.image.v2 =
 openstack.network.v2 =
     address_scope_create = openstackclient.network.v2.address_scope:CreateAddressScope
     address_scope_delete = openstackclient.network.v2.address_scope:DeleteAddressScope
+    address_scope_list = openstackclient.network.v2.address_scope:ListAddressScope
 
     ip_floating_create = openstackclient.network.v2.floating_ip:CreateFloatingIP
     ip_floating_delete = openstackclient.network.v2.floating_ip:DeleteFloatingIP