Merge "Add revert to snapshot support in VxFlex OS driver"

This commit is contained in:
Zuul 2020-04-09 19:48:24 +00:00 committed by Gerrit Code Review
commit c3c7a6328e
6 changed files with 157 additions and 2 deletions

View File

@ -0,0 +1,104 @@
# Copyright (c) 2020 Dell Inc. or its subsidiaries.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from unittest import mock
from cinder import context
from cinder import exception
from cinder.tests.unit import fake_constants as fake
from cinder.tests.unit import fake_snapshot
from cinder.tests.unit import fake_volume
from cinder.tests.unit.volume.drivers.dell_emc import vxflexos
class TestRevertVolume(vxflexos.TestVxFlexOSDriver):
"""Test cases for ``VxFlexOSDriver.revert_to_snapshot()``"""
def setUp(self):
"""Setup a test case environment.
Creates a fake volume object and sets up the required API responses.
"""
super(TestRevertVolume, self).setUp()
ctx = context.RequestContext('fake', 'fake', auth_token=True)
host = 'host@backend#{}:{}'.format(
self.PROT_DOMAIN_NAME,
self.STORAGE_POOL_NAME)
self.volume = fake_volume.fake_volume_obj(
ctx, **{'provider_id': fake.PROVIDER_ID, 'host': host,
'volume_type_id': fake.VOLUME_TYPE_ID,
'size': 8})
self.snapshot = fake_snapshot.fake_snapshot_obj(
ctx, **{'volume_id': self.volume.id,
'volume_size': self.volume.size}
)
self.HTTPS_MOCK_RESPONSES = {
self.RESPONSE_MODE.Valid: {
'instances/Volume::{}/action/overwriteVolumeContent'.format(
self.volume.provider_id
): {},
},
self.RESPONSE_MODE.Invalid: {
'version': "2.6",
},
self.RESPONSE_MODE.BadStatus: {
'instances/Volume::{}/action/overwriteVolumeContent'.format(
self.volume.provider_id
): self.BAD_STATUS_RESPONSE
},
}
self.volume_is_replicated_mock = self.mock_object(
self.volume, 'is_replicated',
return_value=False
)
def test_revert_to_snapshot(self):
self.driver.revert_to_snapshot(None, self.volume, self.snapshot)
def test_revert_to_snapshot_badstatus_response(self):
self.set_https_response_mode(self.RESPONSE_MODE.BadStatus)
self.assertRaises(exception.VolumeBackendAPIException,
self.driver.revert_to_snapshot,
None, self.volume, self.snapshot)
def test_revert_to_snapshot_use_generic(self):
self.set_https_response_mode(self.RESPONSE_MODE.Invalid)
self.assertRaises(NotImplementedError,
self.driver.revert_to_snapshot,
None, self.volume, self.snapshot)
def test_revert_to_snapshot_replicated_volume(self):
self.volume_is_replicated_mock.return_value = True
self.assertRaisesRegexp(
exception.InvalidVolume,
'Reverting replicated volume is not allowed.',
self.driver.revert_to_snapshot,
None, self.volume, self.snapshot
)
def test_revert_to_snapshot_size_not_equal(self):
patched_volume = mock.MagicMock()
patched_volume.id = self.volume.id
patched_volume.size = 16
patched_volume.is_replicated.return_value = False
self.assertRaisesRegexp(
exception.InvalidVolume,
('Volume %s size is not equal to snapshot %s size.' %
(self.volume.id, self.snapshot.id)),
self.driver.revert_to_snapshot,
None, patched_volume, self.snapshot
)

View File

@ -89,9 +89,10 @@ class VxFlexOSDriver(driver.VolumeDriver):
3.5.0 - Add support for VxFlex OS 3.5.x
3.5.1 - Add volume replication v2.1 support for VxFlex OS 3.5.x
3.5.2 - Add volume migration support
3.5.3 - Add revert volume to snapshot support
"""
VERSION = "3.5.2"
VERSION = "3.5.3"
# ThirdPartySystems wiki
CI_WIKI_NAME = "DellEMC_VxFlexOS_CI"
@ -1502,6 +1503,33 @@ class VxFlexOSDriver(driver.VolumeDriver):
location = new_volume.provider_location
return {"_name_id": name_id, "provider_location": location}
def revert_to_snapshot(self, context, volume, snapshot):
"""Revert VxFlex OS volume to the specified snapshot."""
LOG.info("Revert volume %(vol_id)s to snapshot %(snap_id)s.",
{"vol_id": volume.id, "snap_id": snapshot.id})
client = self._get_client()
if not flex_utils.version_gte(client.query_rest_api_version(), "3.0"):
LOG.debug("VxFlex OS versions less than v3.0 do not "
"support reverting volume to snapshot. "
"Falling back to generic revert to snapshot method.")
raise NotImplementedError
elif volume.is_replicated():
msg = _("Reverting replicated volume is not allowed.")
LOG.error(msg)
raise exception.InvalidVolume(reason=msg)
elif snapshot.volume_size != volume.size:
msg = (_("Volume %(vol_id)s size is not equal to snapshot "
"%(snap_id)s size. Revert to snapshot operation is not "
"allowed.") %
{"vol_id": volume.id, "snap_id": snapshot.id})
LOG.error(msg)
raise exception.InvalidVolume(reason=msg)
client.overwrite_volume_content(volume, snapshot)
def _query_vxflexos_volume(self, volume, existing_ref):
type_id = volume.get("volume_type_id")
if "source-id" not in existing_ref:

View File

@ -686,3 +686,20 @@ class RestClient(object):
LOG.error(msg)
raise exception.VolumeBackendAPIException(msg)
return response
def overwrite_volume_content(self, volume, snapshot):
url = "/instances/Volume::%(vol_id)s/action/overwriteVolumeContent"
params = {"srcVolumeId": snapshot.provider_id}
r, response = self.execute_vxflexos_post_request(
url,
params=params,
vol_id=volume.provider_id
)
if r.status_code != http_client.OK:
msg = (_("Failed to revert volume %(vol_id)s to snapshot "
"%(snap_id)s: %(err)s.") % {"vol_id": volume.id,
"snap_id": snapshot.id,
"err": response["message"]})
LOG.error(msg)
raise exception.VolumeBackendAPIException(msg)

View File

@ -73,6 +73,8 @@ Supported operations
* Create a volume from a snapshot
* Revert a volume to a snapshot
* Copy an image to a volume
* Copy a volume to an image

View File

@ -774,7 +774,7 @@ driver.dell_emc_unity=complete
driver.dell_emc_vmax_af=complete
driver.dell_emc_vmax_3=complete
driver.dell_emc_vnx=complete
driver.dell_emc_vxflexos=missing
driver.dell_emc_vxflexos=complete
driver.dell_emc_xtremio=missing
driver.fujitsu_eternus=missing
driver.hpe_3par=complete

View File

@ -0,0 +1,4 @@
---
features:
- |
VxFlex OS driver now supports storage-assisted revert volume to snapshot.