From 0aa2304f38da0696576827fc4d71f2cf7cc13ad6 Mon Sep 17 00:00:00 2001
From: Tang Chen <chen.tang@easystack.cn>
Date: Fri, 17 Jun 2016 15:06:40 +0800
Subject: [PATCH] Transfer "ip floating CRUD" to "floating ip CRUD"

This patch does the following things to transfer
"ip floating xxx" to "floating ip xxx":
* Add new command "floating ip create/delete/list/show", and doc.
* Deprecate "ip floating create/delete/list/show" command.

Change-Id: Ib071acaac81988431244e858bddafa7f93403df5
Implements: blueprint rework-ip-commands
Closes-bug: 1555990
Co-Authored-By: Dean Troyer <dtroyer@gmail.com>
---
 doc/source/command-objects/floating-ip.rst    |  82 +++++++++++++
 doc/source/command-objects/ip-floating.rst    |   4 +
 functional/tests/compute/v2/test_server.py    |  11 +-
 .../tests/network/v2/test_floating_ip.py      |   8 +-
 openstackclient/network/v2/floating_ip.py     | 109 +++++++++++++++++-
 .../ip-command-rework-8d3fe0858f51e6b8.yaml   |   5 +
 setup.cfg                                     |  13 ++-
 7 files changed, 214 insertions(+), 18 deletions(-)
 create mode 100644 doc/source/command-objects/floating-ip.rst

diff --git a/doc/source/command-objects/floating-ip.rst b/doc/source/command-objects/floating-ip.rst
new file mode 100644
index 0000000000..093bb8e481
--- /dev/null
+++ b/doc/source/command-objects/floating-ip.rst
@@ -0,0 +1,82 @@
+===========
+floating ip
+===========
+
+Compute v2, Network v2
+
+floating ip create
+------------------
+
+Create floating IP
+
+.. program:: floating ip create
+.. code:: bash
+
+    os floating ip create
+        [--subnet <subnet>]
+        [--port <port>]
+        [--floating-ip-address <floating-ip-address>]
+        [--fixed-ip-address <fixed-ip-address>]
+        <network>
+
+.. option:: --subnet <subnet>
+
+    Subnet on which you want to create the floating IP (name or ID)
+    *Network version 2 only*
+
+.. option:: --port <port>
+
+    Port to be associated with the floating IP (name or ID)
+    *Network version 2 only*
+
+.. option:: --floating-ip-address <floating-ip-address>
+
+    Floating IP address
+    *Network version 2 only*
+
+.. option:: --fixed-ip-address <fixed-ip-address>
+
+    Fixed IP address mapped to the floating IP
+    *Network version 2 only*
+
+.. describe:: <network>
+
+    Network to allocate floating IP from (name or ID)
+
+floating ip delete
+------------------
+
+Delete floating IP(s)
+
+.. program:: floating ip delete
+.. code:: bash
+
+    os floating ip delete <floating-ip> [<floating-ip> ...]
+
+.. describe:: <floating-ip>
+
+    Floating IP(s) to delete (IP address or ID)
+
+floating ip list
+----------------
+
+List floating IP(s)
+
+.. program:: floating ip list
+.. code:: bash
+
+    os floating ip list
+
+floating ip show
+----------------
+
+Display floating IP details
+
+.. program:: floating ip show
+.. code:: bash
+
+    os floating ip show <floating-ip>
+
+.. describe:: <floating-ip>
+
+    Floating IP to display (IP address or ID)
diff --git a/doc/source/command-objects/ip-floating.rst b/doc/source/command-objects/ip-floating.rst
index 378812d123..7b38a382d8 100644
--- a/doc/source/command-objects/ip-floating.rst
+++ b/doc/source/command-objects/ip-floating.rst
@@ -29,6 +29,7 @@ ip floating create
 ------------------
 
 Create new floating IP address
+(Deprecated, please use ``floating ip create`` instead)
 
 .. program:: ip floating create
 .. code:: bash
@@ -68,6 +69,7 @@ ip floating delete
 ------------------
 
 Delete floating IP(s)
+(Deprecated, please use ``floating ip delete`` instead)
 
 .. program:: ip floating delete
 .. code:: bash
@@ -83,6 +85,7 @@ ip floating list
 ----------------
 
 List floating IP addresses
+(Deprecated, please use ``floating ip list`` instead)
 
 .. program:: ip floating list
 .. code:: bash
@@ -114,6 +117,7 @@ ip floating show
 ----------------
 
 Display floating IP details
+(Deprecated, please use ``floating ip show`` instead)
 
 .. program:: ip floating show
 .. code:: bash
diff --git a/functional/tests/compute/v2/test_server.py b/functional/tests/compute/v2/test_server.py
index 511ac37293..a9d0e9c132 100644
--- a/functional/tests/compute/v2/test_server.py
+++ b/functional/tests/compute/v2/test_server.py
@@ -249,24 +249,25 @@ class ServerTests(test.TestCase):
         self.wait_for_status("ACTIVE")
         # attach ip
         opts = self.get_opts(["id", "floating_ip_address"])
-        raw_output = self.openstack('ip floating create ' +
+        raw_output = self.openstack('floating ip create ' +
                                     self.IP_POOL +
                                     opts)
         ip, ipid, rol = tuple(raw_output.split('\n'))
         self.assertNotEqual("", ipid)
         self.assertNotEqual("", ip)
-        raw_output = self.openstack('ip floating add ' + ip + ' ' + self.NAME)
+        raw_output = self.openstack('server add floating ip ' + self.NAME +
+                                    ' ' + ip)
         self.assertEqual("", raw_output)
         raw_output = self.openstack('server show ' + self.NAME)
         self.assertIn(ip, raw_output)
 
         # detach ip
-        raw_output = self.openstack('ip floating remove ' + ip + ' ' +
-                                    self.NAME)
+        raw_output = self.openstack('server remove floating ip ' + self.NAME +
+                                    ' ' + ip)
         self.assertEqual("", raw_output)
         raw_output = self.openstack('server show ' + self.NAME)
         self.assertNotIn(ip, raw_output)
-        raw_output = self.openstack('ip floating delete ' + ipid)
+        raw_output = self.openstack('floating ip delete ' + ipid)
         self.assertEqual("", raw_output)
 
     def test_server_reboot(self):
diff --git a/functional/tests/network/v2/test_floating_ip.py b/functional/tests/network/v2/test_floating_ip.py
index 3b314b7050..7e7c63f4d4 100644
--- a/functional/tests/network/v2/test_floating_ip.py
+++ b/functional/tests/network/v2/test_floating_ip.py
@@ -35,12 +35,12 @@ class FloatingIpTests(test.TestCase):
         )
         opts = cls.get_opts(cls.FIELDS)
         raw_output = cls.openstack(
-            'ip floating create ' + cls.NETWORK_NAME + opts)
+            'floating ip create ' + cls.NETWORK_NAME + opts)
         cls.ID = raw_output.strip('\n')
 
     @classmethod
     def tearDownClass(cls):
-        raw_output = cls.openstack('ip floating delete ' + cls.ID)
+        raw_output = cls.openstack('floating ip delete ' + cls.ID)
         cls.assertOutput('', raw_output)
         raw_output = cls.openstack('subnet delete ' + cls.SUBNET_NAME)
         cls.assertOutput('', raw_output)
@@ -49,10 +49,10 @@ class FloatingIpTests(test.TestCase):
 
     def test_floating_ip_list(self):
         opts = self.get_opts(self.HEADERS)
-        raw_output = self.openstack('ip floating list' + opts)
+        raw_output = self.openstack('floating ip list' + opts)
         self.assertIn(self.ID, raw_output)
 
     def test_floating_ip_show(self):
         opts = self.get_opts(self.FIELDS)
-        raw_output = self.openstack('ip floating show ' + self.ID + opts)
+        raw_output = self.openstack('floating ip show ' + self.ID + opts)
         self.assertEqual(self.ID + "\n", raw_output)
diff --git a/openstackclient/network/v2/floating_ip.py b/openstackclient/network/v2/floating_ip.py
index 8fbf049e3f..454335f1a5 100644
--- a/openstackclient/network/v2/floating_ip.py
+++ b/openstackclient/network/v2/floating_ip.py
@@ -13,6 +13,8 @@
 
 """IP Floating action implementations"""
 
+import logging
+
 from osc_lib import utils
 
 from openstackclient.i18n import _
@@ -31,25 +33,26 @@ def _get_attrs(client_manager, parsed_args):
     attrs = {}
     network_client = client_manager.network
 
+    # Name of a network could be empty string.
     if parsed_args.network is not None:
         network = network_client.find_network(parsed_args.network,
                                               ignore_missing=False)
         attrs['floating_network_id'] = network.id
 
-    if parsed_args.subnet is not None:
+    if parsed_args.subnet:
         subnet = network_client.find_subnet(parsed_args.subnet,
                                             ignore_missing=False)
         attrs['subnet_id'] = subnet.id
 
-    if parsed_args.port is not None:
+    if parsed_args.port:
         port = network_client.find_port(parsed_args.port,
                                         ignore_missing=False)
         attrs['port_id'] = port.id
 
-    if parsed_args.floating_ip_address is not None:
+    if parsed_args.floating_ip_address:
         attrs['floating_ip_address'] = parsed_args.floating_ip_address
 
-    if parsed_args.fixed_ip_address is not None:
+    if parsed_args.fixed_ip_address:
         attrs['fixed_ip_address'] = parsed_args.fixed_ip_address
 
     return attrs
@@ -110,6 +113,30 @@ class CreateFloatingIP(common.NetworkAndComputeShowOne):
         return (columns, data)
 
 
+class CreateIPFloating(CreateFloatingIP):
+    """Create floating IP"""
+
+    # TODO(tangchen): Remove this class and ``ip floating create`` 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 create" instead.'))
+        return super(CreateIPFloating, 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 create" instead.'))
+        return super(CreateIPFloating, self).take_action_compute(
+            client, parsed_args)
+
+
 class DeleteFloatingIP(common.NetworkAndComputeDelete):
     """Delete floating IP(s)"""
 
@@ -135,6 +162,30 @@ class DeleteFloatingIP(common.NetworkAndComputeDelete):
         client.floating_ips.delete(obj.id)
 
 
+class DeleteIPFloating(DeleteFloatingIP):
+    """Delete floating IP(s)"""
+
+    # TODO(tangchen): Remove this class and ``ip floating delete`` 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 delete" instead.'))
+        return super(DeleteIPFloating, 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 delete" instead.'))
+        return super(DeleteIPFloating, self).take_action_compute(
+            client, parsed_args)
+
+
 class ListFloatingIP(common.NetworkAndComputeLister):
     """List floating IP(s)"""
 
@@ -186,8 +237,32 @@ class ListFloatingIP(common.NetworkAndComputeLister):
                 ) for s in data))
 
 
+class ListIPFloating(ListFloatingIP):
+    """List floating IP(s)"""
+
+    # TODO(tangchen): Remove this class and ``ip floating 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 list" instead.'))
+        return super(ListIPFloating, 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 list" instead.'))
+        return super(ListIPFloating, self).take_action_compute(
+            client, parsed_args)
+
+
 class ShowFloatingIP(common.NetworkAndComputeShowOne):
-    """Show floating IP details"""
+    """Display floating IP details"""
 
     def update_parser_common(self, parser):
         parser.add_argument(
@@ -211,3 +286,27 @@ class ShowFloatingIP(common.NetworkAndComputeShowOne):
         columns = _get_columns(obj._info)
         data = utils.get_dict_properties(obj._info, columns)
         return (columns, data)
+
+
+class ShowIPFloating(ShowFloatingIP):
+    """Display floating IP details"""
+
+    # TODO(tangchen): Remove this class and ``ip floating show`` 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 show" instead.'))
+        return super(ShowIPFloating, 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 show" instead.'))
+        return super(ShowIPFloating, self).take_action_compute(
+            client, parsed_args)
diff --git a/releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml b/releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml
index 6e95eb08aa..c5b7f22890 100644
--- a/releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml
+++ b/releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml
@@ -10,6 +10,9 @@ features:
   - Add new commands ``server add/remove fixed ip``. They are used to
     replace the old commands ``ip fixed add/remove``.
     [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+  - Add new commands ``floating ip create/delete/list/show``. It is used to
+    replace the old commands ``ip floating create/delete/list/show``.
+    [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>`_]
@@ -17,3 +20,5 @@ deprecations:
     [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
   - Deprecate commands ``ip fixed add/remove``.
     [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+  - Deprecate commands ``ip floating create/delete/list/show``.
+    [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
diff --git a/setup.cfg b/setup.cfg
index 0dd368a381..2c7c049c10 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -337,15 +337,20 @@ openstack.network.v2 =
     address_scope_set = openstackclient.network.v2.address_scope:SetAddressScope
     address_scope_show = openstackclient.network.v2.address_scope:ShowAddressScope
 
+    floating_ip_create = openstackclient.network.v2.floating_ip:CreateFloatingIP
+    floating_ip_delete = openstackclient.network.v2.floating_ip:DeleteFloatingIP
+    floating_ip_list = openstackclient.network.v2.floating_ip:ListFloatingIP
+    floating_ip_show = openstackclient.network.v2.floating_ip:ShowFloatingIP
+
     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
 
-    ip_floating_create = openstackclient.network.v2.floating_ip:CreateFloatingIP
-    ip_floating_delete = openstackclient.network.v2.floating_ip:DeleteFloatingIP
-    ip_floating_list = openstackclient.network.v2.floating_ip:ListFloatingIP
-    ip_floating_show = openstackclient.network.v2.floating_ip:ShowFloatingIP
+    ip_floating_create = openstackclient.network.v2.floating_ip:CreateIPFloating
+    ip_floating_delete = openstackclient.network.v2.floating_ip:DeleteIPFloating
+    ip_floating_list = openstackclient.network.v2.floating_ip:ListIPFloating
+    ip_floating_show = openstackclient.network.v2.floating_ip:ShowIPFloating
 
     ip_floating_pool_list = openstackclient.network.v2.floating_ip_pool:ListIPFloatingPool