From 4464109c7754a9287f75ec2af84398700d1450e6 Mon Sep 17 00:00:00 2001
From: ShogoAdachi <sho-adachi@xc.jp.nec.com>
Date: Thu, 7 Sep 2017 19:10:24 +0900
Subject: [PATCH] Accept 0 for --min-disk and --min-ram

The current openstackclient implementation cannot accept 0
for --min-disk and --min-ram with the "openstack image set" command.
If theses options get set to 0, the option parser in openstackclient
wrongly interprets 0 as no option value. The 0 is valid for these
options if administrators want to make it the default(no minimum
requirements).

This patch fix the parser so that it avoids only 'None'.

Change-Id: Ie8ee37484c02c26f54adc56263fcd167c0ce7eb3
Closes-bug: #1719499
---
 openstackclient/image/v1/image.py             |  6 +++--
 openstackclient/image/v2/image.py             |  4 +--
 .../tests/unit/image/v1/test_image.py         | 26 +++++++++++++++++++
 .../tests/unit/image/v2/test_image.py         | 26 +++++++++++++++++++
 .../notes/bug-1719499-d67d80b0da0bc30a.yaml   |  5 ++++
 5 files changed, 63 insertions(+), 4 deletions(-)
 create mode 100644 releasenotes/notes/bug-1719499-d67d80b0da0bc30a.yaml

diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py
index b92da8ce5b..7a8e67bfca 100644
--- a/openstackclient/image/v1/image.py
+++ b/openstackclient/image/v1/image.py
@@ -625,11 +625,11 @@ class SetImage(command.Command):
         kwargs = {}
         copy_attrs = ('name', 'owner', 'min_disk', 'min_ram', 'properties',
                       'container_format', 'disk_format', 'size', 'store',
-                      'location', 'copy_from', 'volume', 'force', 'checksum')
+                      'location', 'copy_from', 'volume', 'checksum')
         for attr in copy_attrs:
             if attr in parsed_args:
                 val = getattr(parsed_args, attr, None)
-                if val:
+                if val is not None:
                     # Only include a value in kwargs for attributes that are
                     # actually present on the command line
                     kwargs[attr] = val
@@ -653,6 +653,8 @@ class SetImage(command.Command):
             kwargs['is_public'] = True
         if parsed_args.private:
             kwargs['is_public'] = False
+        if parsed_args.force:
+            kwargs['force'] = True
 
         # Wrap the call to catch exceptions in order to close files
         try:
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index a2e45fc707..d793c4599b 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -749,7 +749,7 @@ class SetImage(command.Command):
             "--tag",
             dest="tags",
             metavar="<tag>",
-            default=[],
+            default=None,
             action='append',
             help=_("Set a tag on this image "
                    "(repeat option to set multiple tags)"),
@@ -860,7 +860,7 @@ class SetImage(command.Command):
         for attr in copy_attrs:
             if attr in parsed_args:
                 val = getattr(parsed_args, attr, None)
-                if val:
+                if val is not None:
                     # Only include a value in kwargs for attributes that are
                     # actually present on the command line
                     kwargs[attr] = val
diff --git a/openstackclient/tests/unit/image/v1/test_image.py b/openstackclient/tests/unit/image/v1/test_image.py
index 8a83feb0c4..ae578d9138 100644
--- a/openstackclient/tests/unit/image/v1/test_image.py
+++ b/openstackclient/tests/unit/image/v1/test_image.py
@@ -689,6 +689,32 @@ class TestImageSet(TestImage):
         )
         self.assertIsNone(result)
 
+    def test_image_set_numeric_options_to_zero(self):
+        arglist = [
+            '--min-disk', '0',
+            '--min-ram', '0',
+            self._image.name,
+        ]
+        verifylist = [
+            ('min_disk', 0),
+            ('min_ram', 0),
+            ('image', self._image.name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        kwargs = {
+            'min_disk': 0,
+            'min_ram': 0,
+        }
+        # ImageManager.update(image, **kwargs)
+        self.images_mock.update.assert_called_with(
+            self._image.id,
+            **kwargs
+        )
+        self.assertIsNone(result)
+
 
 class TestImageShow(TestImage):
 
diff --git a/openstackclient/tests/unit/image/v2/test_image.py b/openstackclient/tests/unit/image/v2/test_image.py
index 429ddd282b..383619ef54 100644
--- a/openstackclient/tests/unit/image/v2/test_image.py
+++ b/openstackclient/tests/unit/image/v2/test_image.py
@@ -1313,6 +1313,32 @@ class TestImageSet(TestImage):
             exceptions.CommandError,
             self.cmd.take_action, parsed_args)
 
+    def test_image_set_numeric_options_to_zero(self):
+        arglist = [
+            '--min-disk', '0',
+            '--min-ram', '0',
+            image_fakes.image_name,
+        ]
+        verifylist = [
+            ('min_disk', 0),
+            ('min_ram', 0),
+            ('image', image_fakes.image_name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        kwargs = {
+            'min_disk': 0,
+            'min_ram': 0,
+        }
+        # ImageManager.update(image, **kwargs)
+        self.images_mock.update.assert_called_with(
+            image_fakes.image_id,
+            **kwargs
+        )
+        self.assertIsNone(result)
+
 
 class TestImageShow(TestImage):
 
diff --git a/releasenotes/notes/bug-1719499-d67d80b0da0bc30a.yaml b/releasenotes/notes/bug-1719499-d67d80b0da0bc30a.yaml
new file mode 100644
index 0000000000..37fbdc5529
--- /dev/null
+++ b/releasenotes/notes/bug-1719499-d67d80b0da0bc30a.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+  - |
+    Accept ``0`` as a valid value in the ``image set`` ``--min-disk`` and ``--min-ram`` options.
+    .. _bug 1719499: https://bugs.launchpad.net/python-openstackclient/+bug/1719499