From 73d15e3768e28008515781b30e533ddf3d8d4159 Mon Sep 17 00:00:00 2001
From: reedip <reedip.banerjee@nectechnologies.in>
Date: Fri, 1 Apr 2016 14:26:16 +0900
Subject: [PATCH] Add option to clear information from ports

This patch adds the option of "no-fixed-ip" and
"no-binding-profile" which is used to clear the
fixed-ip and binding:profile information from the
ports.

Change-Id: I946301eaf6c647bae55e4f416aa0d98e5f06e699
---
 doc/source/command-objects/port.rst           | 12 +++-
 openstackclient/network/v2/port.py            | 58 ++++++++++++++-----
 openstackclient/tests/network/v2/test_port.py |  6 ++
 ...nset-fixed-ip-option-9b1832d0f7f71eda.yaml |  5 ++
 4 files changed, 64 insertions(+), 17 deletions(-)
 create mode 100644 releasenotes/notes/add-unset-fixed-ip-option-9b1832d0f7f71eda.yaml

diff --git a/doc/source/command-objects/port.rst b/doc/source/command-objects/port.rst
index 46bd6339ae..b666b6528b 100644
--- a/doc/source/command-objects/port.rst
+++ b/doc/source/command-objects/port.rst
@@ -123,11 +123,11 @@ Set port properties
 .. code:: bash
 
     os port set
-        [--fixed-ip subnet=<subnet>,ip-address=<ip-address>]
+        [--fixed-ip subnet=<subnet>,ip-address=<ip-address> | --no-fixed-ip]
         [--device-id <device-id>]
         [--device-owner <device-owner>]
         [--vnic-type <vnic-type>]
-        [--binding-profile <binding-profile>]
+        [--binding-profile <binding-profile> | --no-binding-profile]
         [--host-id <host-id>]
         [--enable | --disable]
         [--name <name>]
@@ -139,6 +139,10 @@ Set port properties
     subnet=<subnet>,ip-address=<ip-address>
     (you can repeat this option)
 
+.. option:: --no-fixed-ip
+
+    Clear existing information of fixed-ips
+
 .. option:: --device-id <device-id>
 
     Device ID of this port
@@ -157,6 +161,10 @@ Set port properties
     Custom data to be passed as binding:profile: <key>=<value>
     (this option can be repeated)
 
+.. option:: --no-binding-profile
+
+    Clear existing information of binding:profile
+
 .. option:: --host-id <host-id>
 
     The ID of the host where the port is allocated
diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py
index d7866cccdf..a9e8042868 100644
--- a/openstackclient/network/v2/port.py
+++ b/openstackclient/network/v2/port.py
@@ -151,14 +151,6 @@ def _prepare_fixed_ips(client_manager, parsed_args):
 
 
 def _add_updatable_args(parser):
-        parser.add_argument(
-            '--fixed-ip',
-            metavar='subnet=<subnet>,ip-address=<ip-address>',
-            action=parseractions.MultiKeyValueAction,
-            optional_keys=['subnet', 'ip-address'],
-            help='Desired IP and/or subnet (name or ID) for this port: '
-                 'subnet=<subnet>,ip-address=<ip-address> '
-                 '(this option can be repeated)')
         # NOTE(dtroyer): --device-id is deprecated in Mar 2016.  Do not
         #                remove before 3.x release or Mar 2017.
         device_group = parser.add_mutually_exclusive_group()
@@ -184,12 +176,6 @@ def _add_updatable_args(parser):
             help="VNIC type for this port (direct | direct-physical |"
                  " macvtap | normal | baremetal). If unspecified during"
                  " port creation, default value will be 'normal'.")
-        parser.add_argument(
-            '--binding-profile',
-            metavar='<binding-profile>',
-            action=parseractions.KeyValueAction,
-            help='Custom data to be passed as binding:profile: <key>=<value> '
-                 '(this option can be repeated)')
         # NOTE(dtroyer): --host-id is deprecated in Mar 2016.  Do not
         #                remove before 3.x release or Mar 2017.
         host_group = parser.add_mutually_exclusive_group()
@@ -217,6 +203,20 @@ class CreatePort(command.ShowOne):
             required=True,
             help='Network this port belongs to (name or ID)')
         _add_updatable_args(parser)
+        parser.add_argument(
+            '--fixed-ip',
+            metavar='subnet=<subnet>,ip-address=<ip-address>',
+            action=parseractions.MultiKeyValueAction,
+            optional_keys=['subnet', 'ip-address'],
+            help='Desired IP and/or subnet (name or ID) for this port: '
+                 'subnet=<subnet>,ip-address=<ip-address> '
+                 '(this option can be repeated)')
+        parser.add_argument(
+            '--binding-profile',
+            metavar='<binding-profile>',
+            action=parseractions.KeyValueAction,
+            help='Custom data to be passed as binding:profile: <key>=<value> '
+                 '(this option can be repeated)')
         admin_group = parser.add_mutually_exclusive_group()
         admin_group.add_argument(
             '--enable',
@@ -352,7 +352,30 @@ class SetPort(command.Command):
             metavar="<port>",
             help=("Port to modify (name or ID)")
         )
-
+        fixed_ip = parser.add_mutually_exclusive_group()
+        fixed_ip.add_argument(
+            '--fixed-ip',
+            metavar='subnet=<subnet>,ip-address=<ip-address>',
+            action=parseractions.MultiKeyValueAction,
+            optional_keys=['subnet', 'ip-address'],
+            help='Desired IP and/or subnet (name or ID) for this port: '
+                 'subnet=<subnet>,ip-address=<ip-address> '
+                 '(this option can be repeated)')
+        fixed_ip.add_argument(
+            '--no-fixed-ip',
+            action='store_true',
+            help='Clear existing information of fixed-ips')
+        binding_profile = parser.add_mutually_exclusive_group()
+        binding_profile.add_argument(
+            '--binding-profile',
+            metavar='<binding-profile>',
+            action=parseractions.KeyValueAction,
+            help='Custom data to be passed as binding:profile: <key>=<value> '
+                 '(this option can be repeated)')
+        binding_profile.add_argument(
+            '--no-binding-profile',
+            action='store_true',
+            help='Clear existing information of binding:profile')
         return parser
 
     def take_action(self, parsed_args):
@@ -361,6 +384,11 @@ class SetPort(command.Command):
         _prepare_fixed_ips(self.app.client_manager, parsed_args)
         attrs = _get_attrs(self.app.client_manager, parsed_args)
 
+        if parsed_args.no_fixed_ip:
+            attrs['fixed_ips'] = []
+        if parsed_args.no_binding_profile:
+            attrs['binding:profile'] = {}
+
         if attrs == {}:
             msg = "Nothing specified to be set"
             raise exceptions.CommandError(msg)
diff --git a/openstackclient/tests/network/v2/test_port.py b/openstackclient/tests/network/v2/test_port.py
index 31454dba57..3b1a641a3e 100644
--- a/openstackclient/tests/network/v2/test_port.py
+++ b/openstackclient/tests/network/v2/test_port.py
@@ -298,10 +298,14 @@ class TestSetPort(TestPort):
     def test_set_this(self):
         arglist = [
             '--disable',
+            '--no-fixed-ip',
+            '--no-binding-profile',
             self._port.name,
         ]
         verifylist = [
             ('disable', True),
+            ('no_binding_profile', True),
+            ('no_fixed_ip', True),
         ]
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -309,6 +313,8 @@ class TestSetPort(TestPort):
 
         attrs = {
             'admin_state_up': False,
+            'binding:profile': {},
+            'fixed_ips': [],
         }
         self.network.update_port.assert_called_once_with(self._port, **attrs)
         self.assertIsNone(result)
diff --git a/releasenotes/notes/add-unset-fixed-ip-option-9b1832d0f7f71eda.yaml b/releasenotes/notes/add-unset-fixed-ip-option-9b1832d0f7f71eda.yaml
new file mode 100644
index 0000000000..759e2ca904
--- /dev/null
+++ b/releasenotes/notes/add-unset-fixed-ip-option-9b1832d0f7f71eda.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - Fixed-IP information and binding profile information
+    in ports can now be cleared using ``--no-fixed-ip``
+    and ``--no-binding-profile`` with ``port set``