Support revert to snapshot in client
This patch added revert to snapshot support in cinder client, also fix two pylint errors. Change-Id: I20d8df8d7bcf763f6651f44901a98f6d853b27ce Partial-Implements: blueprint revert-volume-to-snapshot Depends-On: cca9e1ac54d123da8859ff918b2355606bfa474e
This commit is contained in:
parent
b910f5bea3
commit
7dfbb239de
cinderclient
releasenotes/notes
@ -29,7 +29,7 @@ LOG = logging.getLogger(__name__)
|
||||
# key is a deprecated version and value is an alternative version.
|
||||
DEPRECATED_VERSIONS = {"1": "2"}
|
||||
DEPRECATED_VERSION = "2.0"
|
||||
MAX_VERSION = "3.33"
|
||||
MAX_VERSION = "3.40"
|
||||
MIN_VERSION = "3.0"
|
||||
|
||||
_SUBSTITUTIONS = {}
|
||||
|
@ -535,6 +535,8 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
elif action == 'os-volume_upload_image':
|
||||
assert 'image_name' in body[action]
|
||||
_body = body
|
||||
elif action == 'revert':
|
||||
assert 'snapshot_id' in body[action]
|
||||
else:
|
||||
raise AssertionError("Unexpected action: %s" % action)
|
||||
return (resp, {}, _body)
|
||||
|
@ -23,6 +23,7 @@ from cinderclient import client
|
||||
from cinderclient import exceptions
|
||||
from cinderclient import shell
|
||||
from cinderclient.v3 import volumes
|
||||
from cinderclient.v3 import volume_snapshots
|
||||
from cinderclient.tests.unit import utils
|
||||
from cinderclient.tests.unit.v3 import fakes
|
||||
from cinderclient.tests.unit.fixture_data import keystone_client
|
||||
@ -278,6 +279,18 @@ class ShellTest(utils.TestCase):
|
||||
self.run_command(command)
|
||||
self.assert_called('GET', '/attachments%s' % expected)
|
||||
|
||||
@mock.patch('cinderclient.shell_utils.find_volume_snapshot')
|
||||
def test_revert_to_snapshot(self, mock_snapshot):
|
||||
|
||||
mock_snapshot.return_value = volume_snapshots.Snapshot(
|
||||
self, {'id': '5678', 'volume_id': '1234'})
|
||||
|
||||
self.run_command(
|
||||
'--os-volume-api-version 3.40 revert-to-snapshot 5678')
|
||||
|
||||
self.assert_called('POST', '/volumes/1234/action',
|
||||
body={'revert': {'snapshot_id': '5678'}})
|
||||
|
||||
def test_attachment_show(self):
|
||||
self.run_command('--os-volume-api-version 3.27 attachment-show 1234')
|
||||
self.assert_called('GET', '/attachments/1234')
|
||||
|
@ -18,9 +18,11 @@
|
||||
import ddt
|
||||
|
||||
from cinderclient import api_versions
|
||||
from cinderclient import exceptions
|
||||
from cinderclient.tests.unit import utils
|
||||
from cinderclient.tests.unit.v3 import fakes
|
||||
from cinderclient.v3 import volumes
|
||||
from cinderclient.v3 import volume_snapshots
|
||||
|
||||
from six.moves.urllib import parse
|
||||
|
||||
@ -48,6 +50,28 @@ class VolumesTest(utils.TestCase):
|
||||
visibility='public', protected=True)
|
||||
cs.assert_called_anytime('POST', '/volumes/1234/action', body=expected)
|
||||
|
||||
@ddt.data('3.39', '3.40')
|
||||
def test_revert_to_snapshot(self, version):
|
||||
|
||||
api_version = api_versions.APIVersion(version)
|
||||
cs = fakes.FakeClient(api_version)
|
||||
manager = volumes.VolumeManager(cs)
|
||||
fake_snapshot = volume_snapshots.Snapshot(
|
||||
manager, {'id': 12345, 'name': 'fake-snapshot'}, loaded=True)
|
||||
fake_volume = volumes.Volume(manager,
|
||||
{'id': 1234, 'name': 'sample-volume'},
|
||||
loaded=True)
|
||||
expected = {'revert': {'snapshot_id': 12345}}
|
||||
|
||||
if version == '3.40':
|
||||
fake_volume.revert_to_snapshot(fake_snapshot)
|
||||
|
||||
cs.assert_called_anytime('POST', '/volumes/1234/action',
|
||||
body=expected)
|
||||
else:
|
||||
self.assertRaises(exceptions.VersionNotFoundForAPIMethod,
|
||||
fake_volume.revert_to_snapshot, fake_snapshot)
|
||||
|
||||
def test_create_volume(self):
|
||||
vol = cs.volumes.create(1, group_id='1234', volume_type='5678')
|
||||
expected = {'volume': {'status': 'creating',
|
||||
|
@ -1371,6 +1371,19 @@ def do_api_version(cs, args):
|
||||
utils.print_list(response, columns)
|
||||
|
||||
|
||||
@api_versions.wraps("3.40")
|
||||
@utils.arg(
|
||||
'snapshot',
|
||||
metavar='<snapshot>',
|
||||
help='Name or ID of the snapshot to restore. The snapshot must be the '
|
||||
'most recent one known to cinder.')
|
||||
def do_revert_to_snapshot(cs, args):
|
||||
"""Revert a volume to the specified snapshot."""
|
||||
snapshot = shell_utils.find_volume_snapshot(cs, args.snapshot)
|
||||
volume = utils.find_volume(cs, snapshot.volume_id)
|
||||
volume.revert_to_snapshot(snapshot)
|
||||
|
||||
|
||||
@api_versions.wraps("3.3")
|
||||
@utils.arg('--marker',
|
||||
metavar='<marker>',
|
||||
|
@ -45,6 +45,10 @@ class Volume(volumes.Volume):
|
||||
return self.manager.upload_to_image(self, force, image_name,
|
||||
container_format, disk_format)
|
||||
|
||||
def revert_to_snapshot(self, snapshot):
|
||||
"""Revert a volume to a snapshot."""
|
||||
self.manager.revert_to_snapshot(self, snapshot)
|
||||
|
||||
|
||||
class VolumeManager(volumes.VolumeManager):
|
||||
resource_class = Volume
|
||||
@ -109,6 +113,17 @@ class VolumeManager(volumes.VolumeManager):
|
||||
|
||||
return self._create('/volumes', body, 'volume')
|
||||
|
||||
@api_versions.wraps('3.40')
|
||||
def revert_to_snapshot(self, volume, snapshot):
|
||||
"""Revert a volume to a snapshot.
|
||||
|
||||
The snapshot must be the most recent one known to cinder.
|
||||
:param volume: volume object.
|
||||
:param snapshot: snapshot object.
|
||||
"""
|
||||
return self._action('revert', volume,
|
||||
info={'snapshot_id': base.getid(snapshot.id)})
|
||||
|
||||
@api_versions.wraps("3.0")
|
||||
def delete_metadata(self, volume, keys):
|
||||
"""Delete specified keys from volumes metadata.
|
||||
@ -131,6 +146,7 @@ class VolumeManager(volumes.VolumeManager):
|
||||
:param volume: The :class:`Volume`.
|
||||
:param keys: A list of keys to be removed.
|
||||
"""
|
||||
# pylint: disable=function-redefined
|
||||
data = self._get("/volumes/%s/metadata" % base.getid(volume))
|
||||
metadata = data._info.get("metadata", {})
|
||||
if set(keys).issubset(metadata.keys()):
|
||||
@ -160,6 +176,7 @@ class VolumeManager(volumes.VolumeManager):
|
||||
"""Upload volume to image service as image.
|
||||
:param volume: The :class:`Volume` to upload.
|
||||
"""
|
||||
# pylint: disable=function-redefined
|
||||
return self._action('os-volume_upload_image',
|
||||
volume,
|
||||
{'force': force,
|
||||
|
@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
- Added support for the revert-to-snapshot feature.
|
Loading…
x
Reference in New Issue
Block a user