Nimble: Add support for revert to snapshot

blueprint nimble-add-revert-to-snapshot-support

Change-Id: I63f4ae165486451b8c3da2e5d7a40a4c2a96ad4a
This commit is contained in:
Ajitha Robert 2020-10-12 08:31:27 -04:00
parent 53124744e4
commit 56ee0971b3
5 changed files with 92 additions and 2 deletions

View File

@ -154,6 +154,13 @@ FAKE_IGROUP_LIST_RESPONSE_FC = [
{'wwpn': '10:00:00:00:00:00:00:01'}],
'name': 'test-igrp2'}]
FAKE_GET_VOL_INFO_REVERT = {'name': 'testvolume',
'id': fake.VOLUME_ID,
'clone': False,
'target_name': 'iqn.test',
'online': True,
'agent_type': 'openstack',
'last_snap': {'snap_id': fake.SNAPSHOT_ID}}
FAKE_CREATE_VOLUME_NEGATIVE_RESPONSE = exception.VolumeBackendAPIException(
"Volume testvolume not found")
@ -173,6 +180,9 @@ FAKE_CREATE_VOLUME_NEGATIVE_DEDUPE = exception.VolumeBackendAPIException(
FAKE_CREATE_VOLUME_NEGATIVE_QOS = exception.VolumeBackendAPIException(
"Please set valid IOPS limitin the range [256, 4294967294]")
FAKE_VOLUME_RESTORE_NEGATIVE_RESPONSE = exception.VolumeBackendAPIException(
"No recent Snapshot found")
FAKE_POSITIVE_GROUP_INFO_RESPONSE = {
'version_current': '3.0.0.0',
'group_target_enabled': False,
@ -1189,6 +1199,55 @@ class NimbleDriverSnapshotTestCase(NimbleDriverBaseTestCase):
'limit': 100}})]
self.mock_client_service.assert_has_calls(expected_calls)
@mock.patch(NIMBLE_URLLIB2)
@mock.patch(NIMBLE_CLIENT)
@NimbleDriverBaseTestCase.client_mock_decorator(create_configuration(
'nimble', 'nimble_pass', '10.18.108.55', 'default', '*'))
def test_revert_to_snapshot(self):
self.mock_client_service.online_vol.return_value = (
FAKE_GENERIC_POSITIVE_RESPONSE)
self.mock_client_service.volume_restore.return_value = (
FAKE_GENERIC_POSITIVE_RESPONSE)
self.mock_client_service.get_vol_info.return_value = (
FAKE_GET_VOL_INFO_REVERT)
self.mock_client_service.get_netconfig.return_value = (
FAKE_POSITIVE_NETCONFIG_RESPONSE)
ctx = context.get_admin_context()
self.driver.revert_to_snapshot(ctx,
{'id': fake.VOLUME_ID,
'size': 1,
'name': 'testvolume'},
{'id': fake.SNAPSHOT_ID,
'volume_id': fake.VOLUME_ID})
expected_calls = [mock.call.online_vol('testvolume', False),
mock.call.volume_restore('testvolume',
{'data': {'id': fake.VOLUME_ID,
'base_snap_id': fake.SNAPSHOT_ID}}),
mock.call.online_vol('testvolume', True)]
self.mock_client_service.assert_has_calls(expected_calls)
@mock.patch(NIMBLE_URLLIB2)
@mock.patch(NIMBLE_CLIENT)
@NimbleDriverBaseTestCase.client_mock_decorator(create_configuration(
'nimble', 'nimble_pass', '10.18.108.55', 'default', '*'))
def test_revert_to_snapshot_negative(self):
self.mock_client_service.online_vol.return_value = (
FAKE_GENERIC_POSITIVE_RESPONSE)
self.mock_client_service.volume_restore.side_effect = (
FAKE_VOLUME_RESTORE_NEGATIVE_RESPONSE)
self.mock_client_service.get_vol_info.return_value = (
FAKE_GET_VOL_INFO_REVERT)
self.mock_client_service.get_netconfig.return_value = (
FAKE_POSITIVE_NETCONFIG_RESPONSE)
ctx = context.get_admin_context()
self.assertRaises(exception.VolumeBackendAPIException,
self.driver.revert_to_snapshot, ctx,
{'id': fake.VOLUME_ID,
'size': 1,
'name': 'testvolume'},
{'id': fake.SNAPSHOT_ID,
'volume_id': fake.VOLUME_ID})
class NimbleDriverConnectionTestCase(NimbleDriverBaseTestCase):

View File

@ -737,6 +737,28 @@ class NimbleBaseVolumeDriver(san.SanDriver):
return True
return False
def revert_to_snapshot(self, context, volume, snapshot):
vol_info = self.APIExecutor.get_vol_info(volume['name'])
snap_id = vol_info['last_snap']['snap_id']
volume_id = vol_info['id']
LOG.debug("Reverting volume %(vol)s with snapshot id %(snap_id)s",
{'vol': volume['name'], 'snap_id': snap_id})
data = {'data': {"base_snap_id": snap_id, "id": volume_id}}
try:
self.APIExecutor.online_vol(volume['name'], False)
self.APIExecutor.volume_restore(volume['name'], data)
LOG.info("Volume %(vol)s is successfully restored with "
"snap_id %(snap_id)s",
{'vol': volume['name'], 'snap_id': snap_id})
self.APIExecutor.online_vol(volume['name'], True)
except NimbleAPIException as ex:
raise NimbleAPIException(_("Unable to restore %(vol)s to "
"%(snap_id)s: %(err)s") %
{'vol': volume['name'],
'snap_id': snap_id,
'err': ex.message})
return self._get_model_info(volume['name'])
@interface.volumedriver
class NimbleISCSIDriver(NimbleBaseVolumeDriver, san.SanISCSIDriver):
@ -1846,6 +1868,11 @@ class NimbleRestAPIExecutor(object):
else:
raise
def volume_restore(self, volume_name, data):
volume_id = self.get_volume_id_by_name(volume_name)
api = 'volumes/%s/actions/restore' % volume_id
self.post(api, data)
@_connection_checker
def get(self, api):
return self.get_query(api, None)

View File

@ -38,7 +38,7 @@ Supported operations
* Retype a volume
* Create a Thinly Provisioned Volume
* Attach a volume to multiple servers simultaneously (multiattach)
* Volume Revert to Snapshot
Nimble Storage driver configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -832,7 +832,7 @@ driver.netapp_ontap=missing
driver.netapp_solidfire=complete
driver.nexenta=missing
driver.nfs=missing
driver.nimble=missing
driver.nimble=complete
driver.prophetstor=missing
driver.pure=complete
driver.qnap=missing

View File

@ -0,0 +1,4 @@
---
features:
- |
Added revert to snapshot feature in Nimble driver.