From 50bd56db258a16199463afcdeb2f0579384cc711 Mon Sep 17 00:00:00 2001
From: Tang Chen <chen.tang@easystack.cn>
Date: Fri, 17 Jun 2016 14:39:13 +0800
Subject: [PATCH] Transfer "ip floating pool list" to "floating ip pool list"

This patch does the following things to transfer
"ip floating pool list" to "floating ip pool list":

* Add a new command "floating ip pool list" to deprecate
  "ip floating pool list". The source code is in network/v2
  dir.
* Add doc for "floating ip pool list".
* Add floating ip pool unit tests.

Change-Id: Id410f4e4a96cf589a6e8def209574da71395b55f
Implements: blueprint rework-ip-commands
Partial-bug: 1555990
Co-Authored-By: Dean Troyer <dtroyer@gmail.com>
---
 .../command-objects/floating-ip-pool.rst      | 15 +++
 .../command-objects/ip-floating-pool.rst      |  1 +
 doc/source/commands.rst                       |  1 +
 openstackclient/compute/v2/floatingippool.py  | 36 -------
 .../network/v2/floating_ip_pool.py            | 66 +++++++++++++
 openstackclient/tests/compute/v2/fakes.py     | 51 ++++++++++
 .../tests/network/v2/test_floating_ip_pool.py | 97 +++++++++++++++++++
 .../ip-command-rework-8d3fe0858f51e6b8.yaml   |  9 ++
 setup.cfg                                     |  5 +-
 9 files changed, 244 insertions(+), 37 deletions(-)
 create mode 100644 doc/source/command-objects/floating-ip-pool.rst
 delete mode 100644 openstackclient/compute/v2/floatingippool.py
 create mode 100644 openstackclient/network/v2/floating_ip_pool.py
 create mode 100644 openstackclient/tests/network/v2/test_floating_ip_pool.py
 create mode 100644 releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml

diff --git a/doc/source/command-objects/floating-ip-pool.rst b/doc/source/command-objects/floating-ip-pool.rst
new file mode 100644
index 0000000000..6f074d2d34
--- /dev/null
+++ b/doc/source/command-objects/floating-ip-pool.rst
@@ -0,0 +1,15 @@
+================
+floating ip pool
+================
+
+Compute v2, Network v2
+
+floating ip pool list
+---------------------
+
+List pools of floating IP addresses
+
+.. program:: floating ip pool list
+.. code:: bash
+
+    os floating ip pool list
diff --git a/doc/source/command-objects/ip-floating-pool.rst b/doc/source/command-objects/ip-floating-pool.rst
index 63a450eb40..310974c619 100644
--- a/doc/source/command-objects/ip-floating-pool.rst
+++ b/doc/source/command-objects/ip-floating-pool.rst
@@ -8,6 +8,7 @@ ip floating pool list
 ---------------------
 
 List pools of floating IP addresses
+(Deprecated, please use ``floating ip pool list`` instead)
 
 .. program:: ip floating pool list
 .. code:: bash
diff --git a/doc/source/commands.rst b/doc/source/commands.rst
index 9d8ad6fd26..42268c25bd 100644
--- a/doc/source/commands.rst
+++ b/doc/source/commands.rst
@@ -91,6 +91,7 @@ referring to both Compute and Volume quotas.
 * ``extension``: (**Compute**, **Identity**, **Network**, **Volume**) OpenStack server API extensions
 * ``federation protocol``: (**Identity**) the underlying protocol used while federating identities
 * ``flavor``: (**Compute**) predefined server configurations: ram, root disk and so on
+* ``floating ip pool``: (**Compute**, **Network**) - a pool of public IP addresses
 * ``group``: (**Identity**) a grouping of users
 * ``host``: (**Compute**) - the physical computer running compute services
 * ``hypervisor``: (**Compute**) the virtual machine manager
diff --git a/openstackclient/compute/v2/floatingippool.py b/openstackclient/compute/v2/floatingippool.py
deleted file mode 100644
index 0d46e32b12..0000000000
--- a/openstackclient/compute/v2/floatingippool.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#   Copyright 2013 OpenStack Foundation
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-"""Floating IP Pool action implementations"""
-
-from osc_lib.command import command
-from osc_lib import utils
-
-
-class ListFloatingIPPool(command.Lister):
-    """List pools of floating IP addresses"""
-
-    def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.compute
-
-        columns = ('Name',)
-
-        data = compute_client.floating_ip_pools.list()
-
-        return (columns,
-                (utils.get_item_properties(
-                    s, columns,
-                    formatters={},
-                ) for s in data))
diff --git a/openstackclient/network/v2/floating_ip_pool.py b/openstackclient/network/v2/floating_ip_pool.py
new file mode 100644
index 0000000000..c78ca06a91
--- /dev/null
+++ b/openstackclient/network/v2/floating_ip_pool.py
@@ -0,0 +1,66 @@
+#   Licensed under the Apache License, Version 2.0 (the "License"); you may
+#   not use this file except in compliance with the License. You may obtain
+#   a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#   License for the specific language governing permissions and limitations
+#   under the License.
+#
+
+"""Floating IP Pool action implementations"""
+
+import logging
+
+from osc_lib import exceptions
+from osc_lib import utils
+
+from openstackclient.i18n import _
+from openstackclient.network import common
+
+
+class ListFloatingIPPool(common.NetworkAndComputeLister):
+    """List pools of floating IP addresses"""
+
+    def take_action_network(self, client, parsed_args):
+        msg = _("Floating ip pool operations are only available for "
+                "Compute v2 network.")
+        raise exceptions.CommandError(msg)
+
+    def take_action_compute(self, client, parsed_args):
+        columns = (
+            'Name',
+        )
+        data = client.floating_ip_pools.list()
+
+        return (columns,
+                (utils.get_item_properties(
+                    s, columns,
+                ) for s in data))
+
+
+class ListIPFloatingPool(ListFloatingIPPool):
+    """List pools of floating IP addresses"""
+
+    # TODO(tangchen): Remove this class and ``ip floating pool list`` command
+    #                 two cycles after Mitaka.
+
+    # This notifies cliff to not display the help for this command
+    deprecated = True
+
+    log = logging.getLogger('deprecated')
+
+    def take_action_network(self, client, parsed_args):
+        self.log.warning(_('This command has been deprecated. '
+                           'Please use "floating ip pool list" instead.'))
+        return super(ListIPFloatingPool, self).take_action_network(
+            client, parsed_args)
+
+    def take_action_compute(self, client, parsed_args):
+        self.log.warning(_('This command has been deprecated. '
+                           'Please use "floating ip pool list" instead.'))
+        return super(ListIPFloatingPool, self).take_action_compute(
+            client, parsed_args)
diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py
index b9add2c8f9..f9b1f75f0c 100644
--- a/openstackclient/tests/compute/v2/fakes.py
+++ b/openstackclient/tests/compute/v2/fakes.py
@@ -178,6 +178,9 @@ class FakeComputev2Client(object):
         self.floating_ips = mock.Mock()
         self.floating_ips.resource_class = fakes.FakeResource(None, {})
 
+        self.floating_ip_pools = mock.Mock()
+        self.floating_ip_pools.resource_class = fakes.FakeResource(None, {})
+
         self.networks = mock.Mock()
         self.networks.resource_class = fakes.FakeResource(None, {})
 
@@ -971,6 +974,54 @@ class FakeFloatingIP(object):
         return mock.MagicMock(side_effect=floating_ips)
 
 
+class FakeFloatingIPPool(object):
+    """Fake one or more floating ip pools."""
+
+    @staticmethod
+    def create_one_floating_ip_pool(attrs=None):
+        """Create a fake floating ip pool.
+
+        :param Dictionary attrs:
+            A dictionary with all attributes
+        :return:
+            A FakeResource object, with id, etc
+        """
+        if attrs is None:
+            attrs = {}
+
+        # Set default attributes.
+        floating_ip_pool_attrs = {
+            'name': 'floating-ip-pool-name-' + uuid.uuid4().hex,
+        }
+
+        # Overwrite default attributes.
+        floating_ip_pool_attrs.update(attrs)
+
+        floating_ip_pool = fakes.FakeResource(
+            info=copy.deepcopy(floating_ip_pool_attrs),
+            loaded=True)
+
+        return floating_ip_pool
+
+    @staticmethod
+    def create_floating_ip_pools(attrs=None, count=2):
+        """Create multiple fake floating ip pools.
+
+        :param Dictionary attrs:
+            A dictionary with all attributes
+        :param int count:
+            The number of floating ip pools to fake
+        :return:
+            A list of FakeResource objects faking the floating ip pools
+        """
+        floating_ip_pools = []
+        for i in range(0, count):
+            floating_ip_pools.append(
+                FakeFloatingIPPool.create_one_floating_ip_pool(attrs)
+            )
+        return floating_ip_pools
+
+
 class FakeNetwork(object):
     """Fake one or more networks."""
 
diff --git a/openstackclient/tests/network/v2/test_floating_ip_pool.py b/openstackclient/tests/network/v2/test_floating_ip_pool.py
new file mode 100644
index 0000000000..22d20d202d
--- /dev/null
+++ b/openstackclient/tests/network/v2/test_floating_ip_pool.py
@@ -0,0 +1,97 @@
+#   Licensed under the Apache License, Version 2.0 (the "License"); you may
+#   not use this file except in compliance with the License. You may obtain
+#   a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#   License for the specific language governing permissions and limitations
+#   under the License.
+#
+
+from osc_lib import exceptions
+
+from openstackclient.network.v2 import floating_ip_pool
+from openstackclient.tests.compute.v2 import fakes as compute_fakes
+from openstackclient.tests.network.v2 import fakes as network_fakes
+
+
+# Tests for Network API v2
+#
+class TestFloatingIPPoolNetwork(network_fakes.TestNetworkV2):
+
+    def setUp(self):
+        super(TestFloatingIPPoolNetwork, self).setUp()
+
+        # Get a shortcut to the network client
+        self.network = self.app.client_manager.network
+
+
+class TestListFloatingIPPoolNetwork(TestFloatingIPPoolNetwork):
+
+    def setUp(self):
+        super(TestListFloatingIPPoolNetwork, self).setUp()
+
+        # Get the command object to test
+        self.cmd = floating_ip_pool.ListFloatingIPPool(self.app,
+                                                       self.namespace)
+
+    def test_floating_ip_list(self):
+        arglist = []
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+                          parsed_args)
+
+
+# Tests for Compute network
+#
+class TestFloatingIPPoolCompute(compute_fakes.TestComputev2):
+
+    def setUp(self):
+        super(TestFloatingIPPoolCompute, self).setUp()
+
+        # Get a shortcut to the compute client
+        self.compute = self.app.client_manager.compute
+
+
+class TestListFloatingIPPoolCompute(TestFloatingIPPoolCompute):
+
+    # The floating ip pools to list up
+    floating_ip_pools = \
+        compute_fakes.FakeFloatingIPPool.create_floating_ip_pools(count=3)
+
+    columns = (
+        'Name',
+    )
+
+    data = []
+    for pool in floating_ip_pools:
+        data.append((
+            pool.name,
+        ))
+
+    def setUp(self):
+        super(TestListFloatingIPPoolCompute, self).setUp()
+
+        self.app.client_manager.network_endpoint_enabled = False
+
+        self.compute.floating_ip_pools.list.return_value = \
+            self.floating_ip_pools
+
+        # Get the command object to test
+        self.cmd = floating_ip_pool.ListFloatingIPPool(self.app, None)
+
+    def test_floating_ip_list(self):
+        arglist = []
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.compute.floating_ip_pools.list.assert_called_once_with()
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, list(data))
diff --git a/releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml b/releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml
new file mode 100644
index 0000000000..c5e36cfa08
--- /dev/null
+++ b/releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml
@@ -0,0 +1,9 @@
+---
+features:
+  - Add new command ``floating ip pool list`` to list up all floating ip
+    pools. This command is used to replace the old command
+    ``ip floating pool list``.
+    [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+deprecations:
+  - Deprecate command ``ip floating pool list``.
+    [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
diff --git a/setup.cfg b/setup.cfg
index d41cdc0171..cf78baf798 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -92,7 +92,6 @@ openstack.compute.v2 =
 
     ip_floating_add = openstackclient.compute.v2.floatingip:AddFloatingIP
     ip_floating_remove = openstackclient.compute.v2.floatingip:RemoveFloatingIP
-    ip_floating_pool_list = openstackclient.compute.v2.floatingippool:ListFloatingIPPool
 
     keypair_create = openstackclient.compute.v2.keypair:CreateKeypair
     keypair_delete = openstackclient.compute.v2.keypair:DeleteKeypair
@@ -333,6 +332,8 @@ openstack.network.v2 =
     address_scope_set = openstackclient.network.v2.address_scope:SetAddressScope
     address_scope_show = openstackclient.network.v2.address_scope:ShowAddressScope
 
+    floating_ip_pool_list = openstackclient.network.v2.floating_ip_pool:ListFloatingIPPool
+
     ip_availability_list = openstackclient.network.v2.ip_availability:ListIPAvailability
     ip_availability_show = openstackclient.network.v2.ip_availability:ShowIPAvailability
 
@@ -341,6 +342,8 @@ openstack.network.v2 =
     ip_floating_list = openstackclient.network.v2.floating_ip:ListFloatingIP
     ip_floating_show = openstackclient.network.v2.floating_ip:ShowFloatingIP
 
+    ip_floating_pool_list = openstackclient.network.v2.floating_ip_pool:ListIPFloatingPool
+
     network_create = openstackclient.network.v2.network:CreateNetwork
     network_delete = openstackclient.network.v2.network:DeleteNetwork
     network_list = openstackclient.network.v2.network:ListNetwork