From 06be732705a19ba1f9da3bb96722d6cfd062575d Mon Sep 17 00:00:00 2001 From: Mark Vanderwiel Date: Wed, 13 Jan 2016 16:31:41 -0600 Subject: [PATCH] Add openstack client stack snapshot restore Based from the existing heat command: heat stack-restore Change-Id: I863631b393586d1ecd20c94988e16ef85fb8ad5a Blueprint: heat-support-python-openstackclient --- heatclient/osc/v1/snapshot.py | 37 +++++++++++++++++++ heatclient/tests/unit/osc/v1/test_snapshot.py | 25 +++++++++++++ setup.cfg | 1 + 3 files changed, 63 insertions(+) diff --git a/heatclient/osc/v1/snapshot.py b/heatclient/osc/v1/snapshot.py index 5e891810..52f9e016 100644 --- a/heatclient/osc/v1/snapshot.py +++ b/heatclient/osc/v1/snapshot.py @@ -16,6 +16,7 @@ import logging import six +from cliff import command from cliff import lister from openstackclient.common import exceptions as exc from openstackclient.common import utils @@ -97,3 +98,39 @@ class ShowSnapshot(format_utils.YamlFormat): rows = list(six.itervalues(data)) columns = list(six.iterkeys(data)) return columns, rows + + +class RestoreSnapshot(command.Command): + """Restore stack snapshot""" + + log = logging.getLogger(__name__ + ".RestoreSnapshot") + + def get_parser(self, prog_name): + parser = super(RestoreSnapshot, self).get_parser(prog_name) + parser.add_argument( + 'stack', + metavar='', + help=_('Name or ID of stack containing the snapshot') + ) + parser.add_argument( + 'snapshot', + metavar='', + help=_('ID of the snapshot to restore') + ) + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)' % parsed_args) + heat_client = self.app.client_manager.orchestration + return self._restore_snapshot(heat_client, parsed_args) + + def _restore_snapshot(self, heat_client, parsed_args): + fields = {'stack_id': parsed_args.stack, + 'snapshot_id': parsed_args.snapshot} + try: + heat_client.stacks.restore(**fields) + except heat_exc.HTTPNotFound: + raise exc.CommandError(_('Stack %(stack)s or ' + 'snapshot %(snapshot)s not found.') % + {'stack': parsed_args.stack, + 'snapshot': parsed_args.snapshot}) diff --git a/heatclient/tests/unit/osc/v1/test_snapshot.py b/heatclient/tests/unit/osc/v1/test_snapshot.py index 88513c78..ae23299c 100644 --- a/heatclient/tests/unit/osc/v1/test_snapshot.py +++ b/heatclient/tests/unit/osc/v1/test_snapshot.py @@ -77,3 +77,28 @@ class TestSnapshotShow(TestStack): exc.CommandError, self.cmd.take_action, parsed_args) + + +class TestRestoreSnapshot(TestStack): + def setUp(self): + super(TestRestoreSnapshot, self).setUp() + self.cmd = snapshot.RestoreSnapshot(self.app, None) + self.stack_client.restore = mock.Mock() + + def test_snapshot_restore(self): + arglist = ['my_stack', 'my_snapshot'] + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + self.stack_client.restore.assert_called_with( + snapshot_id='my_snapshot', stack_id='my_stack') + + def test_snapshot_restore_error(self): + self.stack_client.restore.side_effect = heat_exc.HTTPNotFound() + arglist = ['my_stack', 'my_snapshot'] + parsed_args = self.check_parser(self.cmd, arglist, []) + error = self.assertRaises( + exc.CommandError, + self.cmd.take_action, + parsed_args) + self.assertEqual('Stack my_stack or snapshot my_snapshot not found.', + str(error)) diff --git a/setup.cfg b/setup.cfg index d721e5e9..294ae1b1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -56,6 +56,7 @@ openstack.orchestration.v1 = stack_resume = heatclient.osc.v1.stack:ResumeStack stack_show = heatclient.osc.v1.stack:ShowStack stack_snapshot_list = heatclient.osc.v1.snapshot:ListSnapshot + stack_snapshot_restore = heatclient.osc.v1.snapshot:RestoreSnapshot stack_snapshot_show = heatclient.osc.v1.snapshot:ShowSnapshot stack_suspend = heatclient.osc.v1.stack:SuspendStack stack_template_show = heatclient.osc.v1.stack:TemplateShowStack