From e776a4f0260af1d2ae66439e647794395d470578 Mon Sep 17 00:00:00 2001
From: David Rabel <rabel@b1-systems.de>
Date: Fri, 22 Feb 2019 15:21:17 +0100
Subject: [PATCH] Add --attached / --detached parameter to volume set

As to reflect cinder reset-state --attach-status functionality,
this patch adds --attached / --detached parameter to OSC's volume set
command.

Change-Id: Ic8ee928c9ab0e579512cfb7608f63bfcc2993c7b
Closes-Bug: #1745699
---
 doc/source/cli/command-objects/volume.rst     | 17 +++++++++
 .../tests/unit/volume/v2/test_volume.py       | 36 +++++++++++++++++++
 openstackclient/volume/v2/volume.py           | 35 ++++++++++++++++++
 .../notes/bug-1745699-afa7318b9dc96696.yaml   |  7 ++++
 4 files changed, 95 insertions(+)
 create mode 100644 releasenotes/notes/bug-1745699-afa7318b9dc96696.yaml

diff --git a/doc/source/cli/command-objects/volume.rst b/doc/source/cli/command-objects/volume.rst
index 5c86d10deb..fc6188c0a8 100644
--- a/doc/source/cli/command-objects/volume.rst
+++ b/doc/source/cli/command-objects/volume.rst
@@ -262,6 +262,7 @@ Set volume properties
         [--property <key=value> [...] ]
         [--image-property <key=value> [...] ]
         [--state <state>]
+        [--attached | --detached ]
         [--type <volume-type>]
         [--retype-policy <retype-policy>]
         [--bootable | --non-bootable]
@@ -341,6 +342,22 @@ Set volume properties
 
     *Volume version 2 only*
 
+.. option:: --attached
+
+    Set volume attachment status to "attached" (admin only)
+    (This option simply changes the state of the volume in the database with
+    no regard to actual status, exercise caution when using)
+
+    *Volume version 2 only*
+
+.. option:: --deattach
+
+    Set volume attachment status to "detached" (admin only)
+    (This option simply changes the state of the volume in the database with
+    no regard to actual status, exercise caution when using)
+
+    *Volume version 2 only*
+
 .. _volume_set-volume:
 .. describe:: <volume>
 
diff --git a/openstackclient/tests/unit/volume/v2/test_volume.py b/openstackclient/tests/unit/volume/v2/test_volume.py
index 1f53ce9471..dbe69ea0ff 100644
--- a/openstackclient/tests/unit/volume/v2/test_volume.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume.py
@@ -1327,6 +1327,42 @@ class TestVolumeSet(TestVolume):
         self.volumes_mock.reset_state.assert_called_with(
             self.new_volume.id, 'error')
 
+    def test_volume_set_attached(self):
+        arglist = [
+            '--attached',
+            self.new_volume.id
+        ]
+        verifylist = [
+            ('attached', True),
+            ('detached', False),
+            ('volume', self.new_volume.id)
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+        self.volumes_mock.reset_state.assert_called_with(
+            self.new_volume.id, attach_status='attached', state=None)
+        self.assertIsNone(result)
+
+    def test_volume_set_detached(self):
+        arglist = [
+            '--detached',
+            self.new_volume.id
+        ]
+        verifylist = [
+            ('attached', False),
+            ('detached', True),
+            ('volume', self.new_volume.id)
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+        self.volumes_mock.reset_state.assert_called_with(
+            self.new_volume.id, attach_status='detached', state=None)
+        self.assertIsNone(result)
+
     def test_volume_set_bootable(self):
         arglist = [
             ['--bootable', self.new_volume.id],
diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py
index 14a454c228..fa587b5f67 100644
--- a/openstackclient/volume/v2/volume.py
+++ b/openstackclient/volume/v2/volume.py
@@ -559,6 +559,25 @@ class SetVolume(command.Command):
                    'in the database with no regard to actual status, '
                    'exercise caution when using)'),
         )
+        attached_group = parser.add_mutually_exclusive_group()
+        attached_group.add_argument(
+            "--attached",
+            action="store_true",
+            help=_('Set volume attachment status to "attached" '
+                   '(admin only) '
+                   '(This option simply changes the state of the volume '
+                   'in the database with no regard to actual status, '
+                   'exercise caution when using)'),
+        )
+        attached_group.add_argument(
+            "--detached",
+            action="store_true",
+            help=_('Set volume attachment status to "detached" '
+                   '(admin only) '
+                   '(This option simply changes the state of the volume '
+                   'in the database with no regard to actual status, '
+                   'exercise caution when using)'),
+        )
         parser.add_argument(
             '--type',
             metavar='<volume-type>',
@@ -645,6 +664,22 @@ class SetVolume(command.Command):
             except Exception as e:
                 LOG.error(_("Failed to set volume state: %s"), e)
                 result += 1
+        if parsed_args.attached:
+            try:
+                volume_client.volumes.reset_state(
+                    volume.id, state=None,
+                    attach_status="attached")
+            except Exception as e:
+                LOG.error(_("Failed to set volume attach-status: %s"), e)
+                result += 1
+        if parsed_args.detached:
+            try:
+                volume_client.volumes.reset_state(
+                    volume.id, state=None,
+                    attach_status="detached")
+            except Exception as e:
+                LOG.error(_("Failed to set volume attach-status: %s"), e)
+                result += 1
         if parsed_args.bootable or parsed_args.non_bootable:
             try:
                 volume_client.volumes.set_bootable(
diff --git a/releasenotes/notes/bug-1745699-afa7318b9dc96696.yaml b/releasenotes/notes/bug-1745699-afa7318b9dc96696.yaml
new file mode 100644
index 0000000000..68b48cb03d
--- /dev/null
+++ b/releasenotes/notes/bug-1745699-afa7318b9dc96696.yaml
@@ -0,0 +1,7 @@
+---
+features:
+  - |
+    Add ``--attached`` and ``--detached`` options to ``volume set`` command to set the
+    volume status in the database.  This is the functional equivalent to
+    ``cinder reset-state --attach-status``.
+    [`bug 1745699 <https://bugs.launchpad.net/python-openstackclient/+bug/1745699>`_
\ No newline at end of file