Merge "Use provider_id for SolidFire Volume lookups"

This commit is contained in:
Zuul 2018-02-08 00:09:25 +00:00 committed by Gerrit Code Review
commit 1a612d6a5b
2 changed files with 73 additions and 55 deletions

View File

@ -529,7 +529,7 @@ class SolidFireVolumeTestCase(test.TestCase):
'targetSecret': 'shhhh',
'username': 'john-wayne'}]
get_vol_result = [{'volumeID': 5,
get_vol_result = {'volumeID': 5,
'name': 'test_volume',
'accountID': 25,
'sliceCount': 1,
@ -539,7 +539,7 @@ class SolidFireVolumeTestCase(test.TestCase):
'status': "active",
'attributes': {},
'qos': None,
'iqn': 'super_fake_iqn'}]
'iqn': 'super_fake_iqn'}
mod_conf = self.configuration
mod_conf.sf_enable_vag = True
@ -548,7 +548,7 @@ class SolidFireVolumeTestCase(test.TestCase):
'_get_sfaccounts_for_tenant',
return_value=fake_sfaccounts), \
mock.patch.object(sfv,
'_get_volumes_for_account',
'_get_sfvol_by_cinder_vref',
return_value=get_vol_result), \
mock.patch.object(sfv,
'_issue_api_request'), \
@ -556,7 +556,7 @@ class SolidFireVolumeTestCase(test.TestCase):
'_remove_volume_from_vags') as rem_vol:
sfv.delete_volume(testvol)
rem_vol.assert_called_with(get_vol_result[0]['volumeID'])
rem_vol.assert_called_with(get_vol_result['volumeID'])
def test_delete_volume_no_volume_on_backend(self):
fake_sfaccounts = [{'accountID': 5,

View File

@ -160,10 +160,11 @@ class SolidFireDriver(san.SanISCSIDriver):
2.0.9 - Always purge on delete volume
2.0.10 - Add response to debug on retryable errors
2.0.11 - Add ability to failback replicating volumes
2.0.12 - Fix bug #1744005
"""
VERSION = '2.0.11'
VERSION = '2.0.12'
# ThirdPartySystems wiki page
CI_WIKI_NAME = "NetApp_SolidFire_CI"
@ -528,10 +529,6 @@ class SolidFireDriver(san.SanISCSIDriver):
return response
def _get_active_volumes_by_sfaccount(self, account_id, endpoint=None):
return [v for v in self._get_volumes_by_sfaccount(account_id, endpoint)
if v['status'] == "active"]
def _get_volumes_by_sfaccount(self, account_id, endpoint=None):
"""Get all volumes on cluster for specified account."""
params = {'accountID': account_id}
@ -540,6 +537,61 @@ class SolidFireDriver(san.SanISCSIDriver):
params,
endpoint=endpoint)['result']['volumes']
def _get_volumes_for_account(self, sf_account_id, cinder_uuid=None):
# ListVolumesForAccount gives both Active and Deleted
# we require the solidfire accountID, uuid of volume
# is optional
vols = self._get_volumes_by_sfaccount(sf_account_id)
if cinder_uuid:
vlist = [v for v in vols if
cinder_uuid in v['name']]
else:
vlist = [v for v in vols]
vlist = sorted(vlist, key=lambda k: k['volumeID'])
return vlist
def _get_sfvol_by_cinder_vref(self, vref):
sfvol = None
provider_id = vref.get('provider_id', None)
if provider_id:
try:
sf_vid, sf_aid, sf_cluster_id = provider_id.split(' ')
except ValueError:
LOG.warning("Invalid provider_id entry for volume: %s",
vref.id)
else:
# So there shouldn't be any clusters out in the field that are
# running Element < 8.0, but just in case; we'll to a try
# block here and fall back to the old methods just to be safe
try:
sfvol = self._issue_api_request(
'ListVolumes',
{'startVolumeID': sf_vid,
'limit': 1},
version='8.0')['result']['volumes'][0]
except Exception:
pass
if not sfvol:
LOG.info("Failed to find volume by provider_id, "
"attempting ListForAccount")
for account in self._get_sfaccounts_for_tenant(vref.project_id):
sfvols = self._issue_api_request(
'ListVolumesForAccount',
{'accountID': account['accountID']})['result']['volumes']
if len(sfvols) >= 1:
sfvol = sfvols[0]
break
if not sfvol:
# Hmmm, frankly if we get here there's a problem,
# but try one last trick
LOG.info("Failed to find volume by provider_id or account, "
"attempting find by attributes.")
for v in sfvols:
if v['Attributes'].get('uuid', None):
sfvol = v
break
return sfvol
def _get_sfaccount_by_name(self, sf_account_name, endpoint=None):
"""Get SolidFire account object by name."""
sfaccount = None
@ -1077,19 +1129,6 @@ class SolidFireDriver(san.SanISCSIDriver):
raise exception.SolidFireDriverException(msg)
return sf_account
def _get_volumes_for_account(self, sf_account_id, cinder_uuid=None):
# ListVolumesForAccount gives both Active and Deleted
# we require the solidfire accountID, uuid of volume
# is optional
vols = self._get_active_volumes_by_sfaccount(sf_account_id)
if cinder_uuid:
vlist = [v for v in vols if
cinder_uuid in v['name']]
else:
vlist = [v for v in vols]
vlist = sorted(vlist, key=lambda k: k['volumeID'])
return vlist
def _create_vag(self, iqn, vol_id=None):
"""Create a volume access group(vag).
@ -1466,28 +1505,7 @@ class SolidFireDriver(san.SanISCSIDriver):
volumeID is what's guaranteed unique.
"""
sf_vol = None
accounts = self._get_sfaccounts_for_tenant(volume['project_id'])
if accounts is None:
LOG.error("Account for Volume ID %s was not found on "
"the SolidFire Cluster while attempting "
"delete_volume operation!", volume['id'])
LOG.error("This usually means the volume was never "
"successfully created.")
return
for acc in accounts:
vols = self._get_volumes_for_account(acc['accountID'],
volume.name_id)
# Check for migration magic here
if (not vols and (volume.name_id != volume.id)):
vols = self._get_volumes_for_account(acc['accountID'],
volume.id)
if vols:
sf_vol = vols[0]
break
sf_vol = self._get_sfvol_by_cinder_vref(volume)
if sf_vol is not None:
for vp in sf_vol.get('volumePairs', []):
LOG.debug("Deleting paired volume on remote cluster...")