From af5dbf72c4bf5cd0c8b59bf1a914706eff88e21a Mon Sep 17 00:00:00 2001
From: xiexs <xiexs@cn.fujitsu.com>
Date: Thu, 26 Nov 2015 21:00:04 -0500
Subject: [PATCH] Add "openstack server unshelve" into OSC

The unshelve operation is not supported by OSC,
and this patch tries to add it.

Change-Id: Ic60a4616cb63ad21c1a3c8e02611da8bad3a8bd0
Implements: blueprint introduce-shelve-into-osc
---
 doc/source/command-objects/server.rst         | 15 ++++
 doc/source/commands.rst                       |  3 +-
 openstackclient/compute/v2/server.py          | 75 ++++++++++++-------
 .../tests/compute/v2/test_server.py           | 60 ++++++++++-----
 setup.cfg                                     |  1 +
 5 files changed, 108 insertions(+), 46 deletions(-)

diff --git a/doc/source/command-objects/server.rst b/doc/source/command-objects/server.rst
index 6ae4d2543d..657cc5641f 100644
--- a/doc/source/command-objects/server.rst
+++ b/doc/source/command-objects/server.rst
@@ -720,3 +720,18 @@ Unset server properties
 .. describe:: <server>
 
     Server (name or ID)
+
+server unshelve
+---------------
+
+Unshelve server(s)
+
+.. program:: server unshelve
+.. code:: bash
+
+    os server unshelve
+        <server> [<server> ...]
+
+.. describe:: <server>
+
+    Server(s) to unshelve (name or ID)
diff --git a/doc/source/commands.rst b/doc/source/commands.rst
index 90aa481e94..e0742ab441 100644
--- a/doc/source/commands.rst
+++ b/doc/source/commands.rst
@@ -183,7 +183,7 @@ Those actions with an opposite action are noted in parens if applicable.
 * ``revoke`` (``issue``) - revoke a token
 * ``save`` - download an object locally
 * ``set`` (``unset``) - set a property on the object, formerly called metadata
-* ``shelve`` (``unshelve``) - shelve one or more server
+* ``shelve`` (``unshelve``) - shelve one or more servers
 * ``show`` - display detailed information about the specific object
 * ``start`` (``stop``) - start one or more servers
 * ``stop`` (``start``) - stop one or more servers
@@ -192,6 +192,7 @@ Those actions with an opposite action are noted in parens if applicable.
 * ``unpause`` (``pause``) - return one or more paused servers to running state
 * ``unrescue`` (``rescue``) - return a server to normal boot mode
 * ``unset`` (``set``) - remove an attribute of the object
+* ``unshelve`` (``shelve``) - unshelve one or more servers
 
 
 Implementation
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index 875b9a137d..3f39210f16 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -1352,6 +1352,31 @@ class SetServer(command.Command):
                 raise exceptions.CommandError(msg)
 
 
+class ShelveServer(command.Command):
+    """Shelve server(s)"""
+
+    log = logging.getLogger(__name__ + '.ShelveServer')
+
+    def get_parser(self, prog_name):
+        parser = super(ShelveServer, self).get_parser(prog_name)
+        parser.add_argument(
+            'server',
+            metavar='<server>',
+            nargs='+',
+            help=_('Server(s) to shelve (name or ID)'),
+        )
+        return parser
+
+    @utils.log_method(log)
+    def take_action(self, parsed_args):
+        compute_client = self.app.client_manager.compute
+        for server in parsed_args.server:
+            utils.find_resource(
+                compute_client.servers,
+                server,
+            ).shelve()
+
+
 class ShowServer(show.ShowOne):
     """Show server details"""
 
@@ -1389,31 +1414,6 @@ class ShowServer(show.ShowOne):
         return zip(*sorted(six.iteritems(data)))
 
 
-class ShelveServer(command.Command):
-    """Shelve server(s)"""
-
-    log = logging.getLogger(__name__ + '.ShelveServer')
-
-    def get_parser(self, prog_name):
-        parser = super(ShelveServer, self).get_parser(prog_name)
-        parser.add_argument(
-            'server',
-            metavar='<server>',
-            nargs='+',
-            help=_('Server(s) to shelve (name or ID)'),
-        )
-        return parser
-
-    @utils.log_method(log)
-    def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.compute
-        for server in parsed_args.server:
-            utils.find_resource(
-                compute_client.servers,
-                server,
-            ).shelve()
-
-
 class SshServer(command.Command):
     """Ssh to server"""
 
@@ -1748,3 +1748,28 @@ class UnsetServer(command.Command):
                 server,
                 parsed_args.property,
             )
+
+
+class UnshelveServer(command.Command):
+    """Unshelve server(s)"""
+
+    log = logging.getLogger(__name__ + '.UnshelveServer')
+
+    def get_parser(self, prog_name):
+        parser = super(UnshelveServer, self).get_parser(prog_name)
+        parser.add_argument(
+            'server',
+            metavar='<server>',
+            nargs='+',
+            help=_('Server(s) to unshelve (name or ID)'),
+        )
+        return parser
+
+    @utils.log_method(log)
+    def take_action(self, parsed_args):
+        compute_client = self.app.client_manager.compute
+        for server in parsed_args.server:
+            utils.find_resource(
+                compute_client.servers,
+                server,
+            ).unshelve()
diff --git a/openstackclient/tests/compute/v2/test_server.py b/openstackclient/tests/compute/v2/test_server.py
index b3bf5e015b..c22e59a713 100644
--- a/openstackclient/tests/compute/v2/test_server.py
+++ b/openstackclient/tests/compute/v2/test_server.py
@@ -799,6 +799,26 @@ class TestServerResume(TestServer):
         self.run_method_with_servers('resume', 3)
 
 
+class TestServerShelve(TestServer):
+
+    def setUp(self):
+        super(TestServerShelve, self).setUp()
+
+        # Get the command object to test
+        self.cmd = server.ShelveServer(self.app, None)
+
+        # Set shelve method to be tested.
+        self.methods = {
+            'shelve': None,
+        }
+
+    def test_shelve_one_server(self):
+        self.run_method_with_servers('shelve', 1)
+
+    def test_shelve_multi_servers(self):
+        self.run_method_with_servers('shelve', 3)
+
+
 class TestServerStart(TestServer):
 
     def setUp(self):
@@ -899,6 +919,26 @@ class TestServerUnpause(TestServer):
         self.run_method_with_servers('unpause', 3)
 
 
+class TestServerUnshelve(TestServer):
+
+    def setUp(self):
+        super(TestServerUnshelve, self).setUp()
+
+        # Get the command object to test
+        self.cmd = server.UnshelveServer(self.app, None)
+
+        # Set unshelve method to be tested.
+        self.methods = {
+            'unshelve': None,
+        }
+
+    def test_unshelve_one_server(self):
+        self.run_method_with_servers('unshelve', 1)
+
+    def test_unshelve_multi_servers(self):
+        self.run_method_with_servers('unshelve', 3)
+
+
 class TestServerGeneral(testtools.TestCase):
     OLD = {
         'private': [
@@ -949,23 +989,3 @@ class TestServerGeneral(testtools.TestCase):
                           server._get_ip_address, self.OLD, 'public', [4, 6])
         self.assertRaises(exceptions.CommandError,
                           server._get_ip_address, self.OLD, 'private', [6])
-
-
-class TestShelveServer(TestServer):
-
-    def setUp(self):
-        super(TestShelveServer, self).setUp()
-
-        # Get the command object to test
-        self.cmd = server.ShelveServer(self.app, None)
-
-        # Set shelve method to be tested.
-        self.methods = {
-            'shelve': None,
-        }
-
-    def test_shelve_one_server(self):
-        self.run_method_with_servers('shelve', 1)
-
-    def test_shelve_multi_servers(self):
-        self.run_method_with_servers('shelve', 3)
diff --git a/setup.cfg b/setup.cfg
index 6760e84d40..a971446874 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -140,6 +140,7 @@ openstack.compute.v2 =
     server_unpause = openstackclient.compute.v2.server:UnpauseServer
     server_unrescue = openstackclient.compute.v2.server:UnrescueServer
     server_unset = openstackclient.compute.v2.server:UnsetServer
+    server_unshelve = openstackclient.compute.v2.server:UnshelveServer
 
     usage_list = openstackclient.compute.v2.usage:ListUsage
     usage_show = openstackclient.compute.v2.usage:ShowUsage