Dell SC: Updated to utilize provider_id

The Dell SC driver was not using provider_id. For volumes it now
stores the Dell SC instanceId in provider_id. For snapshots it stores
the volume's instanceId in the snapshot's provider_id. Snapshots are
still located by description.

Cleaned up some code. Removed the excessive find_sc calls. Updated
error messages.

Updated tests to use fake uuids.

Change-Id: I6e365ce401b72601475c781fe884671d81097d77
This commit is contained in:
Tom Swanson 2016-03-31 11:52:23 -05:00
parent 281ddeb03f
commit 3d6f53e447
7 changed files with 1011 additions and 1149 deletions

View File

@ -17,6 +17,7 @@ import mock
from cinder import context from cinder import context
from cinder import exception from cinder import exception
from cinder import test from cinder import test
from cinder.tests.unit import fake_constants as fake
from cinder.volume.drivers.dell import dell_storagecenter_api from cinder.volume.drivers.dell import dell_storagecenter_api
from cinder.volume.drivers.dell import dell_storagecenter_fc from cinder.volume.drivers.dell import dell_storagecenter_fc
@ -171,9 +172,6 @@ class DellSCSanFCDriverTestCase(test.TestCase):
'initiator': 'iqn.1993-08.org.debian:01:e1b1312f9e1', 'initiator': 'iqn.1993-08.org.debian:01:e1b1312f9e1',
'wwpns': ['21000024ff30441c', '21000024ff30441d']} 'wwpns': ['21000024ff30441c', '21000024ff30441d']}
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_server', 'find_server',
return_value=None) return_value=None)
@ -183,6 +181,9 @@ class DellSCSanFCDriverTestCase(test.TestCase):
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_volume', 'find_volume',
return_value=VOLUME) return_value=VOLUME)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'get_volume',
return_value=VOLUME)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'map_volume', 'map_volume',
return_value=MAPPING) return_value=MAPPING)
@ -198,14 +199,14 @@ class DellSCSanFCDriverTestCase(test.TestCase):
def test_initialize_connection(self, def test_initialize_connection(self,
mock_find_wwns, mock_find_wwns,
mock_map_volume, mock_map_volume,
mock_get_volume,
mock_find_volume, mock_find_volume,
mock_create_server, mock_create_server,
mock_find_server, mock_find_server,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
volume = {'id': self.volume_name} volume = {'id': fake.volume_id}
connector = self.connector connector = self.connector
res = self.driver.initialize_connection(volume, connector) res = self.driver.initialize_connection(volume, connector)
expected = {'data': expected = {'data':
@ -221,18 +222,18 @@ class DellSCSanFCDriverTestCase(test.TestCase):
self.assertEqual(expected, res, 'Unexpected return data') self.assertEqual(expected, res, 'Unexpected return data')
# verify find_volume has been called and that is has been called twice # verify find_volume has been called and that is has been called twice
mock_find_volume.assert_any_call(self.volume_name) mock_find_volume.assert_called_once_with(fake.volume_id, None)
assert mock_find_volume.call_count == 2 mock_get_volume.assert_called_once_with(self.VOLUME[u'instanceId'])
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_server', 'find_server',
return_value=SCSERVER) return_value=SCSERVER)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_volume', 'find_volume',
return_value=VOLUME) return_value=VOLUME)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'get_volume',
return_value=VOLUME)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'map_volume', 'map_volume',
return_value=MAPPING) return_value=MAPPING)
@ -242,22 +243,19 @@ class DellSCSanFCDriverTestCase(test.TestCase):
def test_initialize_connection_no_wwns(self, def test_initialize_connection_no_wwns(self,
mock_find_wwns, mock_find_wwns,
mock_map_volume, mock_map_volume,
mock_get_volume,
mock_find_volume, mock_find_volume,
mock_find_server, mock_find_server,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
volume = {'id': self.volume_name} volume = {'id': fake.volume_id}
connector = self.connector connector = self.connector
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,
self.driver.initialize_connection, self.driver.initialize_connection,
volume, volume,
connector) connector)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_server', 'find_server',
return_value=None) return_value=None)
@ -279,20 +277,16 @@ class DellSCSanFCDriverTestCase(test.TestCase):
mock_find_volume, mock_find_volume,
mock_create_server, mock_create_server,
mock_find_server, mock_find_server,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
volume = {'id': self.volume_name} volume = {'id': fake.volume_id}
connector = self.connector connector = self.connector
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,
self.driver.initialize_connection, self.driver.initialize_connection,
volume, volume,
connector) connector)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_server', 'find_server',
return_value=SCSERVER) return_value=SCSERVER)
@ -310,20 +304,16 @@ class DellSCSanFCDriverTestCase(test.TestCase):
mock_map_volume, mock_map_volume,
mock_find_volume, mock_find_volume,
mock_find_server, mock_find_server,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
volume = {'name': self.volume_name} volume = {'id': fake.volume_id}
connector = self.connector connector = self.connector
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,
self.driver.initialize_connection, self.driver.initialize_connection,
volume, volume,
connector) connector)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=12345)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_server', 'find_server',
return_value=SCSERVER) return_value=SCSERVER)
@ -341,21 +331,17 @@ class DellSCSanFCDriverTestCase(test.TestCase):
mock_map_volume, mock_map_volume,
mock_find_volume, mock_find_volume,
mock_find_server, mock_find_server,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
# Test case where map_volume returns None (no mappings) # Test case where map_volume returns None (no mappings)
volume = {'id': self.volume_name} volume = {'id': fake.volume_id}
connector = self.connector connector = self.connector
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,
self.driver.initialize_connection, self.driver.initialize_connection,
volume, volume,
connector) connector)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_server', 'find_server',
return_value=SCSERVER) return_value=SCSERVER)
@ -383,11 +369,10 @@ class DellSCSanFCDriverTestCase(test.TestCase):
mock_unmap_volume, mock_unmap_volume,
mock_find_volume, mock_find_volume,
mock_find_server, mock_find_server,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
volume = {'id': self.volume_name} volume = {'id': fake.volume_id}
connector = self.connector connector = self.connector
res = self.driver.terminate_connection(volume, connector) res = self.driver.terminate_connection(volume, connector)
mock_unmap_volume.assert_called_once_with(self.VOLUME, self.SCSERVER) mock_unmap_volume.assert_called_once_with(self.VOLUME, self.SCSERVER)
@ -395,9 +380,6 @@ class DellSCSanFCDriverTestCase(test.TestCase):
'data': {}} 'data': {}}
self.assertEqual(expected, res, 'Unexpected return data') self.assertEqual(expected, res, 'Unexpected return data')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_server', 'find_server',
return_value=None) return_value=None)
@ -425,20 +407,16 @@ class DellSCSanFCDriverTestCase(test.TestCase):
mock_unmap_volume, mock_unmap_volume,
mock_find_volume, mock_find_volume,
mock_find_server, mock_find_server,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
volume = {'name': self.volume_name} volume = {'id': fake.volume_id}
connector = self.connector connector = self.connector
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,
self.driver.terminate_connection, self.driver.terminate_connection,
volume, volume,
connector) connector)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_server', 'find_server',
return_value=SCSERVER) return_value=SCSERVER)
@ -466,20 +444,16 @@ class DellSCSanFCDriverTestCase(test.TestCase):
mock_unmap_volume, mock_unmap_volume,
mock_find_volume, mock_find_volume,
mock_find_server, mock_find_server,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
volume = {'name': self.volume_name} volume = {'id': fake.volume_id}
connector = self.connector connector = self.connector
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,
self.driver.terminate_connection, self.driver.terminate_connection,
volume, volume,
connector) connector)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_server', 'find_server',
return_value=SCSERVER) return_value=SCSERVER)
@ -503,11 +477,10 @@ class DellSCSanFCDriverTestCase(test.TestCase):
mock_unmap_volume, mock_unmap_volume,
mock_find_volume, mock_find_volume,
mock_find_server, mock_find_server,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
volume = {'name': self.volume_name} volume = {'id': fake.volume_id}
connector = self.connector connector = self.connector
# self.assertRaises(exception.VolumeBackendAPIException, # self.assertRaises(exception.VolumeBackendAPIException,
# self.driver.terminate_connection, # self.driver.terminate_connection,
@ -518,9 +491,6 @@ class DellSCSanFCDriverTestCase(test.TestCase):
'data': {}} 'data': {}}
self.assertEqual(expected, res, 'Unexpected return data') self.assertEqual(expected, res, 'Unexpected return data')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_server', 'find_server',
return_value=SCSERVER) return_value=SCSERVER)
@ -548,20 +518,16 @@ class DellSCSanFCDriverTestCase(test.TestCase):
mock_unmap_volume, mock_unmap_volume,
mock_find_volume, mock_find_volume,
mock_find_server, mock_find_server,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
volume = {'name': self.volume_name} volume = {'id': fake.volume_id}
connector = self.connector connector = self.connector
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,
self.driver.terminate_connection, self.driver.terminate_connection,
volume, volume,
connector) connector)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_server', 'find_server',
return_value=SCSERVER) return_value=SCSERVER)
@ -589,12 +555,11 @@ class DellSCSanFCDriverTestCase(test.TestCase):
mock_unmap_volume, mock_unmap_volume,
mock_find_volume, mock_find_volume,
mock_find_server, mock_find_server,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
# Test case where get_volume_count is zero # Test case where get_volume_count is zero
volume = {'id': self.volume_name} volume = {'id': fake.volume_id}
connector = self.connector connector = self.connector
res = self.driver.terminate_connection(volume, connector) res = self.driver.terminate_connection(volume, connector)
mock_unmap_volume.assert_called_once_with(self.VOLUME, self.SCSERVER) mock_unmap_volume.assert_called_once_with(self.VOLUME, self.SCSERVER)
@ -607,15 +572,11 @@ class DellSCSanFCDriverTestCase(test.TestCase):
'driver_volume_type': 'fibre_channel'} 'driver_volume_type': 'fibre_channel'}
self.assertEqual(expected, res, 'Unexpected return data') self.assertEqual(expected, res, 'Unexpected return data')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'get_storage_usage', 'get_storage_usage',
return_value={'availableSpace': 100, 'freeSpace': 50}) return_value={'availableSpace': 100, 'freeSpace': 50})
def test_update_volume_stats_with_refresh(self, def test_update_volume_stats_with_refresh(self,
mock_get_storage_usage, mock_get_storage_usage,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
@ -623,15 +584,11 @@ class DellSCSanFCDriverTestCase(test.TestCase):
self.assertEqual('FC', stats['storage_protocol']) self.assertEqual('FC', stats['storage_protocol'])
mock_get_storage_usage.assert_called_once_with() mock_get_storage_usage.assert_called_once_with()
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_sc',
return_value=64702)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'get_storage_usage', 'get_storage_usage',
return_value={'availableSpace': 100, 'freeSpace': 50}) return_value={'availableSpace': 100, 'freeSpace': 50})
def test_get_volume_stats_no_refresh(self, def test_get_volume_stats_no_refresh(self,
mock_get_storage_usage, mock_get_storage_usage,
mock_find_sc,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):

File diff suppressed because it is too large Load Diff

View File

@ -1682,6 +1682,7 @@ class DellSCSanAPITestCase(test.TestCase):
self.volid = str(uuid.uuid4()) self.volid = str(uuid.uuid4())
self.volume_name = "volume" + self.volid self.volume_name = "volume" + self.volid
self.repl_name = "Cinder repl of volume" + self.volid
def test_path_to_array(self, def test_path_to_array(self,
mock_close_connection, mock_close_connection,
@ -2006,7 +2007,7 @@ class DellSCSanAPITestCase(test.TestCase):
self.assertEqual(self.FLDR, res, 'Unexpected Folder') self.assertEqual(self.FLDR, res, 'Unexpected Folder')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_volume', 'get_volume',
return_value=VOLUME) return_value=VOLUME)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'unmap_volume', 'unmap_volume',
@ -2025,7 +2026,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_get_json, mock_get_json,
mock_map_volume, mock_map_volume,
mock_unmap_volume, mock_unmap_volume,
mock_find_volume, mock_get_volume,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
@ -2141,7 +2142,7 @@ class DellSCSanAPITestCase(test.TestCase):
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_volume', '_search_for_volume',
return_value=VOLUME) return_value=VOLUME)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_json', '_get_json',
@ -2156,7 +2157,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_post, mock_post,
mock_find_volume_folder, mock_find_volume_folder,
mock_get_json, mock_get_json,
mock_find_volume, mock_search_for_volume,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
@ -2167,7 +2168,7 @@ class DellSCSanAPITestCase(test.TestCase):
1) 1)
self.assertTrue(mock_post.called) self.assertTrue(mock_post.called)
self.assertTrue(mock_get_json.called) self.assertTrue(mock_get_json.called)
self.assertTrue(mock_find_volume.called) mock_search_for_volume.assert_called_once_with(self.volume_name)
mock_find_volume_folder.assert_called_once_with(True) mock_find_volume_folder.assert_called_once_with(True)
self.assertEqual(self.VOLUME, res, 'Unexpected ScVolume') self.assertEqual(self.VOLUME, res, 'Unexpected ScVolume')
@ -2277,103 +2278,195 @@ class DellSCSanAPITestCase(test.TestCase):
self.assertIsNone(res, 'None expected') self.assertIsNone(res, 'None expected')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_volume_list', '_search_for_volume',
return_value=VOLUME_LIST) return_value=VOLUME)
def test_find_volume(self, def test_find_volume(self,
mock_get_vol_list, mock_search_for_volume,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
# Test case to find volume by name # Test case to find volume by name
res = self.scapi.find_volume(self.volume_name) res = self.scapi.find_volume(self.volume_name, None)
self.assertTrue(mock_get_vol_list.called) mock_search_for_volume.assert_called_once_with(self.volume_name)
self.assertEqual(self.VOLUME, res)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_search_for_volume',
return_value=None)
def test_find_volume_not_found(self,
mock_search_for_volume,
mock_close_connection,
mock_open_connection,
mock_init):
# Test case to find volume by name
res = self.scapi.find_volume(self.volume_name, None)
mock_search_for_volume.assert_called_once_with(self.volume_name)
self.assertIsNone(res)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'get_volume',
return_value=VOLUME)
def test_find_volume_with_provider_id(self,
mock_get_volume,
mock_close_connection,
mock_open_connection,
mock_init):
provider_id = str(self.scapi.ssn) + '.1'
res = self.scapi.find_volume(self.volume_name, provider_id)
mock_get_volume.assert_called_once_with(provider_id)
self.assertEqual(self.VOLUME, res)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'get_volume')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_search_for_volume',
return_value=VOLUME)
def test_find_volume_with_invalid_provider_id(self,
mock_search_for_volume,
mock_get_volume,
mock_close_connection,
mock_open_connection,
mock_init):
provider_id = 'WrongSSN.1'
res = self.scapi.find_volume(self.volume_name, provider_id)
mock_search_for_volume.assert_called_once_with(self.volume_name)
self.assertFalse(mock_get_volume.called)
self.assertEqual(self.VOLUME, res)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'get_volume',
return_value=None)
def test_find_volume_with_provider_id_not_found(self,
mock_get_volume,
mock_close_connection,
mock_open_connection,
mock_init):
provider_id = str(self.scapi.ssn) + '.1'
res = self.scapi.find_volume(self.volume_name, provider_id)
mock_get_volume.assert_called_once_with(provider_id)
self.assertIsNone(res)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'get_volume')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_import_one',
return_value=VOLUME)
def test_find_volume_with_provider_id_complete_replication(
self,
mock_import_one,
mock_get_volume,
mock_close_connection,
mock_open_connection,
mock_init):
provider_id = str(self.scapi.ssn) + '.1'
# Configure to middle of failover.
self.scapi.failed_over = True
mock_get_volume.return_value = {'name': self.repl_name}
res = self.scapi.find_volume(self.volume_name, provider_id)
self.scapi.failed_over = False
mock_import_one.assert_called_once_with(mock_get_volume.return_value,
self.volume_name)
mock_get_volume.assert_called_once_with(provider_id)
self.assertEqual(self.VOLUME, res, 'Unexpected volume') self.assertEqual(self.VOLUME, res, 'Unexpected volume')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'get_volume')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_import_one',
return_value=None)
def test_find_volume_with_provider_id_import_fail(self,
mock_import_one,
mock_get_volume,
mock_close_connection,
mock_open_connection,
mock_init):
provider_id = str(self.scapi.ssn) + '.1'
# Configure to middle of failover.
self.scapi.failed_over = True
mock_get_volume.return_value = {'name': self.repl_name}
self.assertRaises(exception.VolumeBackendAPIException,
self.scapi.find_volume, self.volume_name,
provider_id)
self.scapi.failed_over = False
mock_import_one.assert_called_once_with(mock_get_volume.return_value,
self.volume_name)
mock_get_volume.assert_called_once_with(provider_id)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_volume_list', '_get_volume_list',
return_value=None) return_value=None)
def test_find_volume_no_name(self, def test_search_for_volume_no_name(self,
mock_get_volume_list, mock_get_volume_list,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
# Test calling find_volume with no name or instanceid # Test calling find_volume with no name or instanceid
res = self.scapi.find_volume(None) res = self.scapi._search_for_volume(None)
self.assertIsNone(res, 'Expected None') self.assertIsNone(res)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_volume_list') '_get_volume_list')
def test_find_volume_not_found(self, def test_search_for_volume_not_found(self,
mock_get_volume_list, mock_get_volume_list,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
# Test calling find_volume with result of no volume found # Test calling find_volume with result of no volume found
mock_get_volume_list.side_effect = [[], []] mock_get_volume_list.side_effect = [[], []]
res = self.scapi.find_volume(self.volume_name) res = self.scapi._search_for_volume(self.volume_name)
self.assertIsNone(res, 'None expected') self.assertIsNone(res)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_import_one',
return_value=VOLUME)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_volume_list')
def test_find_volume_complete_replication(self,
mock_get_volume_list,
mock_import_one,
mock_close_connection,
mock_open_connection,
mock_init):
self.scapi.failed_over = True
mock_get_volume_list.side_effect = [[], [], self.VOLUME_LIST]
res = self.scapi.find_volume(self.volume_name)
self.assertEqual(self.VOLUME, res, 'Unexpected volume')
self.scapi.failed_over = False
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_import_one',
return_value=None)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_volume_list')
def test_find_volume_complete_replication_fail(self,
mock_get_volume_list,
mock_import_one,
mock_close_connection,
mock_open_connection,
mock_init):
self.scapi.failed_over = True
mock_get_volume_list.side_effect = [[], [], self.VOLUME_LIST]
self.assertRaises(exception.VolumeBackendAPIException,
self.scapi.find_volume, self.volume_name)
self.scapi.failed_over = False
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_volume_list')
def test_find_volume_complete_replication_multi(self,
mock_get_volume_list,
mock_close_connection,
mock_open_connection,
mock_init):
# Test case where multiple repl volumes are found.
mock_get_volume_list.side_effect = [[],
[],
self.VOLUME_LIST_MULTI_VOLS]
self.scapi.failed_over = True
self.assertRaises(exception.VolumeBackendAPIException,
self.scapi.find_volume, self.volume_name)
self.scapi.failed_over = False
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_volume_list', '_get_volume_list',
return_value=VOLUME_LIST_MULTI_VOLS) return_value=VOLUME_LIST_MULTI_VOLS)
def test_find_volume_multi_vols_found(self, def test_search_for_volume_multi_vols_found(self,
mock_get_volume_list, mock_get_volume_list,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
# Test case where multiple volumes are found # Test case where multiple volumes are found
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,
self.scapi.find_volume, self.volume_name) self.scapi._search_for_volume, self.volume_name)
@mock.patch.object(dell_storagecenter_api.HttpClient,
'get',
return_value=RESPONSE_200)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_json',
return_value=VOLUME)
def test_get_volume(self,
mock_get_json,
mock_get,
mock_close_connection,
mock_open_connection,
mock_init):
provider_id = str(self.scapi.ssn) + '.1'
res = self.scapi.get_volume(provider_id)
mock_get.assert_called_once_with(
'StorageCenter/ScVolume/' + provider_id)
self.assertEqual(self.VOLUME, res)
@mock.patch.object(dell_storagecenter_api.HttpClient,
'get',
return_value=RESPONSE_400)
def test_get_volume_error(self,
mock_get,
mock_close_connection,
mock_open_connection,
mock_init):
provider_id = str(self.scapi.ssn) + '.1'
res = self.scapi.get_volume(provider_id)
mock_get.assert_called_once_with(
'StorageCenter/ScVolume/' + provider_id)
self.assertIsNone(res)
def test_get_volume_no_id(self,
mock_close_connection,
mock_open_connection,
mock_init):
provider_id = None
res = self.scapi.get_volume(provider_id)
self.assertIsNone(res)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_json', '_get_json',
@ -2382,10 +2475,10 @@ class DellSCSanAPITestCase(test.TestCase):
'delete', 'delete',
return_value=RESPONSE_200) return_value=RESPONSE_200)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_volume', '_search_for_volume',
return_value=VOLUME) return_value=VOLUME)
def test_delete_volume(self, def test_delete_volume(self,
mock_find_volume, mock_search_for_volume,
mock_delete, mock_delete,
mock_get_json, mock_get_json,
mock_close_connection, mock_close_connection,
@ -2393,35 +2486,52 @@ class DellSCSanAPITestCase(test.TestCase):
mock_init): mock_init):
res = self.scapi.delete_volume(self.volume_name) res = self.scapi.delete_volume(self.volume_name)
self.assertTrue(mock_delete.called) self.assertTrue(mock_delete.called)
mock_find_volume.assert_called_once_with(self.volume_name) mock_search_for_volume.assert_called_once_with(self.volume_name)
self.assertTrue(mock_get_json.called)
self.assertTrue(res)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_json',
return_value=True)
@mock.patch.object(dell_storagecenter_api.HttpClient,
'delete',
return_value=RESPONSE_200)
def test_delete_volume_with_provider_id(self,
mock_delete,
mock_get_json,
mock_close_connection,
mock_open_connection,
mock_init):
provider_id = str(self.scapi.ssn) + '.1'
res = self.scapi.delete_volume(self.volume_name, provider_id)
self.assertTrue(mock_delete.called)
self.assertTrue(mock_get_json.called) self.assertTrue(mock_get_json.called)
self.assertTrue(res) self.assertTrue(res)
@mock.patch.object(dell_storagecenter_api.HttpClient, @mock.patch.object(dell_storagecenter_api.HttpClient,
'delete', 'delete',
return_value=RESPONSE_400) return_value=RESPONSE_400)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_volume',
return_value=VOLUME)
def test_delete_volume_failure(self, def test_delete_volume_failure(self,
mock_find_volume,
mock_delete, mock_delete,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
provider_id = str(self.scapi.ssn) + '.1'
self.assertRaises(exception.VolumeBackendAPIException, self.assertRaises(exception.VolumeBackendAPIException,
self.scapi.delete_volume, self.volume_name) self.scapi.delete_volume, self.volume_name,
provider_id)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_volume', '_search_for_volume',
return_value=None) return_value=None)
def test_delete_volume_no_vol_found(self, def test_delete_volume_no_vol_found(self,
mock_find_volume, mock_search_for_volume,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
# Test case where volume to be deleted does not exist # Test case where volume to be deleted does not exist
res = self.scapi.delete_volume(self.volume_name) res = self.scapi.delete_volume(self.volume_name, None)
mock_search_for_volume.assert_called_once_with(self.volume_name)
self.assertTrue(res, 'Expected True') self.assertTrue(res, 'Expected True')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@ -2484,8 +2594,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_open_connection, mock_open_connection,
mock_init): mock_init):
res = self.scapi._add_hba(self.SCSERVER, res = self.scapi._add_hba(self.SCSERVER,
self.IQN, self.IQN)
False)
self.assertTrue(mock_post.called) self.assertTrue(mock_post.called)
self.assertTrue(res) self.assertTrue(res)
@ -2497,11 +2606,13 @@ class DellSCSanAPITestCase(test.TestCase):
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
saveproto = self.scapi.protocol
self.scapi.protocol = 'FibreChannel'
res = self.scapi._add_hba(self.SCSERVER, res = self.scapi._add_hba(self.SCSERVER,
self.WWN, self.WWN)
True)
self.assertTrue(mock_post.called) self.assertTrue(mock_post.called)
self.assertTrue(res) self.assertTrue(res)
self.scapi.protocol = saveproto
@mock.patch.object(dell_storagecenter_api.HttpClient, @mock.patch.object(dell_storagecenter_api.HttpClient,
'post', 'post',
@ -2512,8 +2623,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_open_connection, mock_open_connection,
mock_init): mock_init):
res = self.scapi._add_hba(self.SCSERVER, res = self.scapi._add_hba(self.SCSERVER,
self.IQN, self.IQN)
False)
self.assertTrue(mock_post.called) self.assertTrue(mock_post.called)
self.assertFalse(res) self.assertFalse(res)
@ -2605,9 +2715,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
res = self.scapi.create_server( res = self.scapi.create_server(self.IQN)
self.IQN,
False)
self.assertTrue(mock_find_serveros.called) self.assertTrue(mock_find_serveros.called)
self.assertTrue(mock_find_server_folder.called) self.assertTrue(mock_find_server_folder.called)
self.assertTrue(mock_first_result.called) self.assertTrue(mock_first_result.called)
@ -2638,9 +2746,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
res = self.scapi.create_server( res = self.scapi.create_server(self.IQN)
self.IQN,
False)
self.assertTrue(mock_find_serveros.called) self.assertTrue(mock_find_serveros.called)
self.assertEqual(self.SCSERVER, res, 'Unexpected ScServer') self.assertEqual(self.SCSERVER, res, 'Unexpected ScServer')
@ -2668,9 +2774,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
res = self.scapi.create_server( res = self.scapi.create_server(self.IQN)
self.IQN,
False)
self.assertTrue(mock_find_server_folder.called) self.assertTrue(mock_find_server_folder.called)
self.assertEqual(self.SCSERVER, res, 'Unexpected ScServer') self.assertEqual(self.SCSERVER, res, 'Unexpected ScServer')
@ -2698,9 +2802,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
res = self.scapi.create_server( res = self.scapi.create_server(self.IQN)
self.IQN,
False)
self.assertIsNone(res, 'None expected') self.assertIsNone(res, 'None expected')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@ -2728,9 +2830,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_open_connection, mock_open_connection,
mock_init): mock_init):
# Test create server where _first_result is None # Test create server where _first_result is None
res = self.scapi.create_server( res = self.scapi.create_server(self.IQN)
self.IQN,
False)
self.assertIsNone(res, 'None expected') self.assertIsNone(res, 'None expected')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@ -2762,9 +2862,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_open_connection, mock_open_connection,
mock_init): mock_init):
# Tests create server where add hba fails # Tests create server where add hba fails
res = self.scapi.create_server( res = self.scapi.create_server(self.IQN)
self.IQN,
False)
self.assertTrue(mock_delete_server.called) self.assertTrue(mock_delete_server.called)
self.assertIsNone(res, 'None expected') self.assertIsNone(res, 'None expected')
@ -2891,13 +2989,13 @@ class DellSCSanAPITestCase(test.TestCase):
@mock.patch.object(dell_storagecenter_api.HttpClient, @mock.patch.object(dell_storagecenter_api.HttpClient,
'get', 'get',
return_value=RESPONSE_200) return_value=RESPONSE_200)
def test_find_fc_initiators(self, def test_find_initiators(self,
mock_get, mock_get,
mock_get_json, mock_get_json,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
res = self.scapi._find_fc_initiators(self.SCSERVER) res = self.scapi._find_initiators(self.SCSERVER)
self.assertTrue(mock_get.called) self.assertTrue(mock_get.called)
self.assertTrue(mock_get_json.called) self.assertTrue(mock_get_json.called)
self.assertIsNotNone(res, 'Expected WWN list') self.assertIsNotNone(res, 'Expected WWN list')
@ -2905,13 +3003,13 @@ class DellSCSanAPITestCase(test.TestCase):
@mock.patch.object(dell_storagecenter_api.HttpClient, @mock.patch.object(dell_storagecenter_api.HttpClient,
'get', 'get',
return_value=RESPONSE_400) return_value=RESPONSE_400)
def test_find_fc_initiators_error(self, def test_find_initiators_error(self,
mock_get, mock_get,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
# Test case where get of ScServer HbaList fails # Test case where get of ScServer HbaList fails
res = self.scapi._find_fc_initiators(self.SCSERVER) res = self.scapi._find_initiators(self.SCSERVER)
self.assertListEqual([], res, 'Expected empty list') self.assertListEqual([], res, 'Expected empty list')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@ -3090,10 +3188,10 @@ class DellSCSanAPITestCase(test.TestCase):
'_find_mappings', '_find_mappings',
return_value=FC_MAPPINGS) return_value=FC_MAPPINGS)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_find_fc_initiators', '_find_initiators',
return_value=WWNS) return_value=WWNS)
def test_find_wwns(self, def test_find_wwns(self,
mock_find_fc_initiators, mock_find_initiators,
mock_find_mappings, mock_find_mappings,
mock_find_controller_port, mock_find_controller_port,
mock_close_connection, mock_close_connection,
@ -3101,7 +3199,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_init): mock_init):
lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME, lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME,
self.SCSERVER) self.SCSERVER)
self.assertTrue(mock_find_fc_initiators.called) self.assertTrue(mock_find_initiators.called)
self.assertTrue(mock_find_mappings.called) self.assertTrue(mock_find_mappings.called)
self.assertTrue(mock_find_controller_port.called) self.assertTrue(mock_find_controller_port.called)
@ -3118,10 +3216,10 @@ class DellSCSanAPITestCase(test.TestCase):
'_find_mappings', '_find_mappings',
return_value=[]) return_value=[])
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_find_fc_initiators', '_find_initiators',
return_value=FC_HBAS) return_value=FC_HBAS)
def test_find_wwns_no_mappings(self, def test_find_wwns_no_mappings(self,
mock_find_fc_initiators, mock_find_initiators,
mock_find_mappings, mock_find_mappings,
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
@ -3129,7 +3227,7 @@ class DellSCSanAPITestCase(test.TestCase):
# Test case where there are no ScMapping(s) # Test case where there are no ScMapping(s)
lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME, lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME,
self.SCSERVER) self.SCSERVER)
self.assertTrue(mock_find_fc_initiators.called) self.assertTrue(mock_find_initiators.called)
self.assertTrue(mock_find_mappings.called) self.assertTrue(mock_find_mappings.called)
self.assertIsNone(lun, 'Incorrect LUN') self.assertIsNone(lun, 'Incorrect LUN')
self.assertEqual([], wwns, 'WWNs is not empty') self.assertEqual([], wwns, 'WWNs is not empty')
@ -3142,10 +3240,10 @@ class DellSCSanAPITestCase(test.TestCase):
'_find_mappings', '_find_mappings',
return_value=FC_MAPPINGS) return_value=FC_MAPPINGS)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_find_fc_initiators', '_find_initiators',
return_value=WWNS) return_value=WWNS)
def test_find_wwns_no_ctlr_port(self, def test_find_wwns_no_ctlr_port(self,
mock_find_fc_initiators, mock_find_initiators,
mock_find_mappings, mock_find_mappings,
mock_find_controller_port, mock_find_controller_port,
mock_close_connection, mock_close_connection,
@ -3154,7 +3252,7 @@ class DellSCSanAPITestCase(test.TestCase):
# Test case where ScControllerPort is none # Test case where ScControllerPort is none
lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME, lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME,
self.SCSERVER) self.SCSERVER)
self.assertTrue(mock_find_fc_initiators.called) self.assertTrue(mock_find_initiators.called)
self.assertTrue(mock_find_mappings.called) self.assertTrue(mock_find_mappings.called)
self.assertTrue(mock_find_controller_port.called) self.assertTrue(mock_find_controller_port.called)
self.assertIsNone(lun, 'Incorrect LUN') self.assertIsNone(lun, 'Incorrect LUN')
@ -3168,10 +3266,10 @@ class DellSCSanAPITestCase(test.TestCase):
'_find_mappings', '_find_mappings',
return_value=FC_MAPPINGS) return_value=FC_MAPPINGS)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_find_fc_initiators', '_find_initiators',
return_value=WWNS) return_value=WWNS)
def test_find_wwns_wwn_error(self, def test_find_wwns_wwn_error(self,
mock_find_fc_initiators, mock_find_initiators,
mock_find_mappings, mock_find_mappings,
mock_find_controller_port, mock_find_controller_port,
mock_close_connection, mock_close_connection,
@ -3181,7 +3279,7 @@ class DellSCSanAPITestCase(test.TestCase):
# property # property
lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME, lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME,
self.SCSERVER) self.SCSERVER)
self.assertTrue(mock_find_fc_initiators.called) self.assertTrue(mock_find_initiators.called)
self.assertTrue(mock_find_mappings.called) self.assertTrue(mock_find_mappings.called)
self.assertTrue(mock_find_controller_port.called) self.assertTrue(mock_find_controller_port.called)
@ -3196,11 +3294,11 @@ class DellSCSanAPITestCase(test.TestCase):
'_find_mappings', '_find_mappings',
return_value=FC_MAPPINGS) return_value=FC_MAPPINGS)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_find_fc_initiators', '_find_initiators',
return_value=WWNS_NO_MATCH) return_value=WWNS_NO_MATCH)
# Test case where HBA name is not found in list of initiators # Test case where HBA name is not found in list of initiators
def test_find_wwns_hbaname_not_found(self, def test_find_wwns_hbaname_not_found(self,
mock_find_fc_initiators, mock_find_initiators,
mock_find_mappings, mock_find_mappings,
mock_find_controller_port, mock_find_controller_port,
mock_close_connection, mock_close_connection,
@ -3208,7 +3306,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_init): mock_init):
lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME, lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME,
self.SCSERVER) self.SCSERVER)
self.assertTrue(mock_find_fc_initiators.called) self.assertTrue(mock_find_initiators.called)
self.assertTrue(mock_find_mappings.called) self.assertTrue(mock_find_mappings.called)
self.assertTrue(mock_find_controller_port.called) self.assertTrue(mock_find_controller_port.called)
@ -3223,11 +3321,11 @@ class DellSCSanAPITestCase(test.TestCase):
'_find_mappings', '_find_mappings',
return_value=FC_MAPPINGS_LUN_MISMATCH) return_value=FC_MAPPINGS_LUN_MISMATCH)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_find_fc_initiators', '_find_initiators',
return_value=WWNS) return_value=WWNS)
# Test case where FC mappings contain a LUN mismatch # Test case where FC mappings contain a LUN mismatch
def test_find_wwns_lun_mismatch(self, def test_find_wwns_lun_mismatch(self,
mock_find_fc_initiators, mock_find_initiators,
mock_find_mappings, mock_find_mappings,
mock_find_controller_port, mock_find_controller_port,
mock_close_connection, mock_close_connection,
@ -3235,7 +3333,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_init): mock_init):
lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME, lun, wwns, itmap = self.scapi.find_wwns(self.VOLUME,
self.SCSERVER) self.SCSERVER)
self.assertTrue(mock_find_fc_initiators.called) self.assertTrue(mock_find_initiators.called)
self.assertTrue(mock_find_mappings.called) self.assertTrue(mock_find_mappings.called)
self.assertTrue(mock_find_controller_port.called) self.assertTrue(mock_find_controller_port.called)
# The _find_controller_port is Mocked, so all mapping pairs # The _find_controller_port is Mocked, so all mapping pairs
@ -3887,7 +3985,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
server = {'instanceId': 64702.48} server = {'instanceId': 64702.48, 'name': 'Server X'}
res = self.scapi.map_volume(self.VOLUME, res = self.scapi.map_volume(self.VOLUME,
server) server)
self.assertTrue(mock_find_mappings.called) self.assertTrue(mock_find_mappings.called)
@ -5008,7 +5106,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_open_connection, mock_open_connection,
mock_init): mock_init):
profileid = '100' profileid = '100'
add_volumes = [{'id': '1'}] add_volumes = [{'id': '1', 'provider_id': '1'}]
res = self.scapi._add_cg_volumes(profileid, add_volumes) res = self.scapi._add_cg_volumes(profileid, add_volumes)
self.assertTrue(mock_find_volume.called) self.assertTrue(mock_find_volume.called)
mock_update_volume_profiles.assert_called_once_with(999, mock_update_volume_profiles.assert_called_once_with(999,
@ -5029,7 +5127,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_open_connection, mock_open_connection,
mock_init): mock_init):
profileid = '100' profileid = '100'
add_volumes = [{'id': '1'}] add_volumes = [{'id': '1', 'provider_id': '1'}]
res = self.scapi._add_cg_volumes(profileid, add_volumes) res = self.scapi._add_cg_volumes(profileid, add_volumes)
self.assertTrue(mock_find_volume.called) self.assertTrue(mock_find_volume.called)
mock_update_volume_profiles.assert_called_once_with(999, mock_update_volume_profiles.assert_called_once_with(999,
@ -5050,7 +5148,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_open_connection, mock_open_connection,
mock_init): mock_init):
profileid = '100' profileid = '100'
remove_volumes = [{'id': '1'}] remove_volumes = [{'id': '1', 'provider_id': '1'}]
res = self.scapi._remove_cg_volumes(profileid, remove_volumes) res = self.scapi._remove_cg_volumes(profileid, remove_volumes)
self.assertTrue(mock_find_volume.called) self.assertTrue(mock_find_volume.called)
mock_update_volume_profiles.assert_called_once_with(999, mock_update_volume_profiles.assert_called_once_with(999,
@ -5071,7 +5169,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_open_connection, mock_open_connection,
mock_init): mock_init):
profileid = '100' profileid = '100'
remove_volumes = [{'id': '1'}] remove_volumes = [{'id': '1', 'provider_id': '1'}]
res = self.scapi._remove_cg_volumes(profileid, remove_volumes) res = self.scapi._remove_cg_volumes(profileid, remove_volumes)
self.assertTrue(mock_find_volume.called) self.assertTrue(mock_find_volume.called)
mock_update_volume_profiles.assert_called_once_with(999, mock_update_volume_profiles.assert_called_once_with(999,
@ -6099,7 +6197,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
ret = self.scapi.find_repl_volume('guid', 65495) ret = self.scapi._find_repl_volume('guid', 65495)
self.assertDictEqual(self.SCREPL[0], ret) self.assertDictEqual(self.SCREPL[0], ret)
@mock.patch.object(dell_storagecenter_api.HttpClient, @mock.patch.object(dell_storagecenter_api.HttpClient,
@ -6114,7 +6212,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
ret = self.scapi.find_repl_volume('guid', 65495) ret = self.scapi._find_repl_volume('guid', 65495)
self.assertIsNone(ret) self.assertIsNone(ret)
@mock.patch.object(dell_storagecenter_api.HttpClient, @mock.patch.object(dell_storagecenter_api.HttpClient,
@ -6129,7 +6227,7 @@ class DellSCSanAPITestCase(test.TestCase):
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
ret = self.scapi.find_repl_volume('guid', 65495) ret = self.scapi._find_repl_volume('guid', 65495)
self.assertIsNone(ret) self.assertIsNone(ret)
@mock.patch.object(dell_storagecenter_api.HttpClient, @mock.patch.object(dell_storagecenter_api.HttpClient,
@ -6140,13 +6238,13 @@ class DellSCSanAPITestCase(test.TestCase):
mock_close_connection, mock_close_connection,
mock_open_connection, mock_open_connection,
mock_init): mock_init):
ret = self.scapi.find_repl_volume('guid', 65495) ret = self.scapi._find_repl_volume('guid', 65495)
self.assertIsNone(ret) self.assertIsNone(ret)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'get_screplication') 'get_screplication')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_repl_volume') '_find_repl_volume')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'find_volume') 'find_volume')
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@ -6182,19 +6280,18 @@ class DellSCSanAPITestCase(test.TestCase):
True, # 3 True, # 3
True, True,
False] # 4 False] # 4
# Good path. # Good path.
ret = self.scapi.break_replication('name', 65495) ret = self.scapi.break_replication('name', None, 65495)
self.assertTrue(ret) self.assertEqual(self.VOLUME, ret)
# Source found, screpl not found. # Source found, screpl not found.
ret = self.scapi.break_replication('name', 65495) ret = self.scapi.break_replication('name', None, 65495)
self.assertTrue(ret) self.assertEqual(self.VOLUME, ret)
# No source vol good path. # No source vol good path.
ret = self.scapi.break_replication('name', 65495) ret = self.scapi.break_replication('name', None, 65495)
self.assertTrue(ret) self.assertEqual(self.VOLUME, ret)
# fail remove mappings # fail remove mappings
ret = self.scapi.break_replication('name', 65495) ret = self.scapi.break_replication('name', None, 65495)
self.assertFalse(ret) self.assertEqual(self.VOLUME, ret)
@mock.patch.object(dell_storagecenter_api.StorageCenterApi, @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
'_get_user_preferences') '_get_user_preferences')

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
# Copyright 2015 Dell Inc. # Copyright 2016 Dell Inc.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
@ -63,6 +63,7 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
self.is_direct_connect = False self.is_direct_connect = False
self.active_backend_id = kwargs.get('active_backend_id', None) self.active_backend_id = kwargs.get('active_backend_id', None)
self.failed_over = (self.active_backend_id is not None) self.failed_over = (self.active_backend_id is not None)
self.storage_protocol = 'iSCSI'
def _bytes_to_gb(self, spacestring): def _bytes_to_gb(self, spacestring):
"""Space is returned in a string like ... """Space is returned in a string like ...
@ -90,7 +91,7 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
specific helpers. specific helpers.
""" """
self._client = dell_storagecenter_api.StorageCenterApiHelper( self._client = dell_storagecenter_api.StorageCenterApiHelper(
self.configuration, self.active_backend_id) self.configuration, self.active_backend_id, self.storage_protocol)
def check_for_setup_error(self): def check_for_setup_error(self):
"""Validates the configuration information.""" """Validates the configuration information."""
@ -227,15 +228,14 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
scvolume = None scvolume = None
with self._client.open_connection() as api: with self._client.open_connection() as api:
try: try:
if api.find_sc(): scvolume = api.create_volume(volume_name,
scvolume = api.create_volume(volume_name, volume_size,
volume_size, storage_profile,
storage_profile, replay_profile_string)
replay_profile_string) if scvolume is None:
if scvolume is None: raise exception.VolumeBackendAPIException(
raise exception.VolumeBackendAPIException( message=_('Unable to create volume %s') %
message=_('Unable to create volume %s') % volume_name)
volume_name)
# Update Consistency Group # Update Consistency Group
self._add_volume_to_consistency_group(api, scvolume, volume) self._add_volume_to_consistency_group(api, scvolume, volume)
@ -243,6 +243,9 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
# Create replications. (Or not. It checks.) # Create replications. (Or not. It checks.)
model_update = self._create_replications(api, volume, scvolume) model_update = self._create_replications(api, volume, scvolume)
# Save our provider_id.
model_update['provider_id'] = scvolume['instanceId']
except Exception: except Exception:
# if we actually created a volume but failed elsewhere # if we actually created a volume but failed elsewhere
# clean up the volume now. # clean up the volume now.
@ -288,20 +291,22 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
""" """
do_repl, sync = self._do_repl(api, volume) do_repl, sync = self._do_repl(api, volume)
if do_repl: if do_repl:
volume_name = volume.get('id')
scvol = api.find_volume(volume_name)
replication_driver_data = volume.get('replication_driver_data') replication_driver_data = volume.get('replication_driver_data')
# This is just a string of ssns separated by commas. if replication_driver_data:
ssnstrings = self._split_driver_data(replication_driver_data) ssnstrings = self._split_driver_data(replication_driver_data)
# Trundle through these and delete them all. volume_name = volume.get('id')
for ssnstring in ssnstrings: provider_id = volume.get('provider_id')
ssn = int(ssnstring) scvol = api.find_volume(volume_name, provider_id)
if not api.delete_replication(scvol, ssn): # This is just a string of ssns separated by commas.
LOG.warning(_LW('Unable to delete replication of ' # Trundle through these and delete them all.
'Volume %(vname)s to Storage Center ' for ssnstring in ssnstrings:
'%(sc)s.'), ssn = int(ssnstring)
{'vname': volume_name, if not api.delete_replication(scvol, ssn):
'sc': ssnstring}) LOG.warning(_LW('Unable to delete replication of '
'Volume %(vname)s to Storage Center '
'%(sc)s.'),
{'vname': volume_name,
'sc': ssnstring})
# If none of that worked or there was nothing to do doesn't matter. # If none of that worked or there was nothing to do doesn't matter.
# Just move on. # Just move on.
@ -309,12 +314,12 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
deleted = False deleted = False
# We use id as our name as it is unique. # We use id as our name as it is unique.
volume_name = volume.get('id') volume_name = volume.get('id')
provider_id = volume.get('provider_id')
LOG.debug('Deleting volume %s', volume_name) LOG.debug('Deleting volume %s', volume_name)
with self._client.open_connection() as api: with self._client.open_connection() as api:
try: try:
if api.find_sc(): self._delete_replications(api, volume)
self._delete_replications(api, volume) deleted = api.delete_volume(volume_name, provider_id)
deleted = api.delete_volume(volume_name)
except Exception: except Exception:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
LOG.error(_LE('Failed to delete volume %s'), LOG.error(_LE('Failed to delete volume %s'),
@ -330,22 +335,23 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
"""Create snapshot""" """Create snapshot"""
# our volume name is the volume id # our volume name is the volume id
volume_name = snapshot.get('volume_id') volume_name = snapshot.get('volume_id')
# TODO(tswanson): Is there any reason to think this will be set
# before I create the snapshot? Doesn't hurt to try to get it.
provider_id = snapshot.get('provider_id')
snapshot_id = snapshot.get('id') snapshot_id = snapshot.get('id')
LOG.debug('Creating snapshot %(snap)s on volume %(vol)s', LOG.debug('Creating snapshot %(snap)s on volume %(vol)s',
{'snap': snapshot_id, {'snap': snapshot_id,
'vol': volume_name}) 'vol': volume_name})
with self._client.open_connection() as api: with self._client.open_connection() as api:
if api.find_sc(): scvolume = api.find_volume(volume_name, provider_id)
scvolume = api.find_volume(volume_name) if scvolume is not None:
if scvolume is not None: replay = api.create_replay(scvolume, snapshot_id, 0)
if api.create_replay(scvolume, if replay:
snapshot_id, return {'status': 'available',
0) is not None: 'provider_id': scvolume['instanceId']}
snapshot['status'] = 'available' else:
return LOG.warning(_LW('Unable to locate volume:%s'),
else: volume_name)
LOG.warning(_LW('Unable to locate volume:%s'),
volume_name)
snapshot['status'] = 'error_creating' snapshot['status'] = 'error_creating'
msg = _('Failed to create snapshot %s') % snapshot_id msg = _('Failed to create snapshot %s') % snapshot_id
@ -355,6 +361,8 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
"""Create new volume from other volume's snapshot on appliance.""" """Create new volume from other volume's snapshot on appliance."""
model_update = {} model_update = {}
scvolume = None scvolume = None
volume_name = volume.get('id')
src_provider_id = snapshot.get('provider_id')
src_volume_name = snapshot.get('volume_id') src_volume_name = snapshot.get('volume_id')
# This snapshot could have been created on its own or as part of a # This snapshot could have been created on its own or as part of a
# cgsnapshot. If it was a cgsnapshot it will be identified on the Dell # cgsnapshot. If it was a cgsnapshot it will be identified on the Dell
@ -365,7 +373,6 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
snapshot_id = snapshot.get('cgsnapshot_id') snapshot_id = snapshot.get('cgsnapshot_id')
if not snapshot_id: if not snapshot_id:
snapshot_id = snapshot.get('id') snapshot_id = snapshot.get('id')
volume_name = volume.get('id')
LOG.debug( LOG.debug(
'Creating new volume %(vol)s from snapshot %(snap)s ' 'Creating new volume %(vol)s from snapshot %(snap)s '
'from vol %(src)s', 'from vol %(src)s',
@ -374,43 +381,42 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
'src': src_volume_name}) 'src': src_volume_name})
with self._client.open_connection() as api: with self._client.open_connection() as api:
try: try:
if api.find_sc(): srcvol = api.find_volume(src_volume_name, src_provider_id)
srcvol = api.find_volume(src_volume_name) if srcvol is not None:
if srcvol is not None: replay = api.find_replay(srcvol, snapshot_id)
replay = api.find_replay(srcvol, if replay is not None:
snapshot_id) # See if we have any extra specs.
if replay is not None: specs = self._get_volume_extra_specs(volume)
volume_name = volume.get('id') replay_profile_string = specs.get(
# See if we have any extra specs. 'storagetype:replayprofiles')
specs = self._get_volume_extra_specs(volume) scvolume = api.create_view_volume(
replay_profile_string = specs.get( volume_name, replay, replay_profile_string)
'storagetype:replayprofiles')
scvolume = api.create_view_volume(
volume_name, replay, replay_profile_string)
# Extend Volume # Extend Volume
if scvolume and (volume['size'] > if scvolume and (volume['size'] >
snapshot["volume_size"]): snapshot["volume_size"]):
LOG.debug("Resize the new volume to %s.", LOG.debug('Resize the new volume to %s.',
volume['size']) volume['size'])
scvolume = api.expand_volume(scvolume, scvolume = api.expand_volume(scvolume,
volume['size']) volume['size'])
if scvolume is None:
raise exception.VolumeBackendAPIException(
message=_('Unable to create volume '
'%(name)s from %(snap)s.') %
{'name': volume_name,
'snap': snapshot_id})
if scvolume is None: # Update Consistency Group
raise exception.VolumeBackendAPIException( self._add_volume_to_consistency_group(api,
message=_('Unable to create volume ' scvolume,
'%(name)s from %(snap)s.') % volume)
{'name': volume_name, # Replicate if we are supposed to.
'snap': snapshot_id}) model_update = self._create_replications(api,
volume,
# Update Consistency Group scvolume)
self._add_volume_to_consistency_group(api, # Save our instanceid.
scvolume, model_update['provider_id'] = (
volume) scvolume['instanceId'])
# Replicate if we are supposed to.
model_update = self._create_replications(api,
volume,
scvolume)
except Exception: except Exception:
# Clean up after ourselves. # Clean up after ourselves.
@ -433,46 +439,46 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
model_update = {} model_update = {}
scvolume = None scvolume = None
src_volume_name = src_vref.get('id') src_volume_name = src_vref.get('id')
src_provider_id = src_vref.get('provider_id')
volume_name = volume.get('id') volume_name = volume.get('id')
LOG.debug('Creating cloned volume %(clone)s from volume %(vol)s', LOG.debug('Creating cloned volume %(clone)s from volume %(vol)s',
{'clone': volume_name, {'clone': volume_name,
'vol': src_volume_name}) 'vol': src_volume_name})
with self._client.open_connection() as api: with self._client.open_connection() as api:
try: try:
if api.find_sc(): srcvol = api.find_volume(src_volume_name, src_provider_id)
srcvol = api.find_volume(src_volume_name) if srcvol is not None:
if srcvol is not None: # See if we have any extra specs.
# See if we have any extra specs. specs = self._get_volume_extra_specs(volume)
specs = self._get_volume_extra_specs(volume) replay_profile_string = specs.get(
replay_profile_string = specs.get( 'storagetype:replayprofiles')
'storagetype:replayprofiles') # Create our volume
# Create our volume scvolume = api.create_cloned_volume(
scvolume = api.create_cloned_volume( volume_name, srcvol, replay_profile_string)
volume_name, srcvol, replay_profile_string)
# Extend Volume # Extend Volume
if scvolume and volume['size'] > src_vref['size']: if scvolume and volume['size'] > src_vref['size']:
LOG.debug("Resize the new volume to %s.", LOG.debug('Resize the volume to %s.', volume['size'])
volume['size']) scvolume = api.expand_volume(scvolume, volume['size'])
scvolume = api.expand_volume(scvolume,
volume['size'])
# If either of those didn't work we bail. # If either of those didn't work we bail.
if scvolume is None: if scvolume is None:
raise exception.VolumeBackendAPIException( raise exception.VolumeBackendAPIException(
message=_('Unable to create volume ' message=_('Unable to create volume '
'%(name)s from %(vol)s.') % '%(name)s from %(vol)s.') %
{'name': volume_name, {'name': volume_name,
'vol': src_volume_name}) 'vol': src_volume_name})
# Update Consistency Group # Update Consistency Group
self._add_volume_to_consistency_group(api, self._add_volume_to_consistency_group(api,
scvolume, scvolume,
volume) volume)
# Replicate if we are supposed to. # Replicate if we are supposed to.
model_update = self._create_replications(api, model_update = self._create_replications(api,
volume, volume,
scvolume) scvolume)
# Save our provider_id.
model_update['provider_id'] = scvolume['instanceId']
except Exception: except Exception:
# Clean up after ourselves. # Clean up after ourselves.
self._cleanup_failed_create_volume(api, volume_name) self._cleanup_failed_create_volume(api, volume_name)
@ -492,16 +498,14 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
"""delete_snapshot""" """delete_snapshot"""
volume_name = snapshot.get('volume_id') volume_name = snapshot.get('volume_id')
snapshot_id = snapshot.get('id') snapshot_id = snapshot.get('id')
provider_id = snapshot.get('provider_id')
LOG.debug('Deleting snapshot %(snap)s from volume %(vol)s', LOG.debug('Deleting snapshot %(snap)s from volume %(vol)s',
{'snap': snapshot_id, {'snap': snapshot_id,
'vol': volume_name}) 'vol': volume_name})
with self._client.open_connection() as api: with self._client.open_connection() as api:
if api.find_sc(): scvolume = api.find_volume(volume_name, provider_id)
scvolume = api.find_volume(volume_name) if scvolume and api.delete_replay(scvolume, snapshot_id):
if scvolume is not None: return
if api.delete_replay(scvolume,
snapshot_id):
return
# if we are here things went poorly. # if we are here things went poorly.
snapshot['status'] = 'error_deleting' snapshot['status'] = 'error_deleting'
msg = _('Failed to delete snapshot %s') % snapshot_id msg = _('Failed to delete snapshot %s') % snapshot_id
@ -513,7 +517,6 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
The volume exists on creation and will be visible on The volume exists on creation and will be visible on
initialize connection. So nothing to do here. initialize connection. So nothing to do here.
""" """
# TODO(tswanson): Move mapping code here.
pass pass
def ensure_export(self, context, volume): def ensure_export(self, context, volume):
@ -524,11 +527,11 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
""" """
scvolume = None scvolume = None
volume_name = volume.get('id') volume_name = volume.get('id')
provider_id = volume.get('provider_id')
LOG.debug('Checking existence of volume %s', volume_name) LOG.debug('Checking existence of volume %s', volume_name)
with self._client.open_connection() as api: with self._client.open_connection() as api:
try: try:
if api.find_sc(): scvolume = api.find_volume(volume_name, provider_id)
scvolume = api.find_volume(volume_name)
except Exception: except Exception:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
LOG.error(_LE('Failed to ensure export of volume %s'), LOG.error(_LE('Failed to ensure export of volume %s'),
@ -548,15 +551,15 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
def extend_volume(self, volume, new_size): def extend_volume(self, volume, new_size):
"""Extend the size of the volume.""" """Extend the size of the volume."""
volume_name = volume.get('id') volume_name = volume.get('id')
provider_id = volume.get('provider_id')
LOG.debug('Extending volume %(vol)s to %(size)s', LOG.debug('Extending volume %(vol)s to %(size)s',
{'vol': volume_name, {'vol': volume_name,
'size': new_size}) 'size': new_size})
if volume is not None: if volume is not None:
with self._client.open_connection() as api: with self._client.open_connection() as api:
if api.find_sc(): scvolume = api.find_volume(volume_name, provider_id)
scvolume = api.find_volume(volume_name) if api.expand_volume(scvolume, new_size) is not None:
if api.expand_volume(scvolume, new_size) is not None: return
return
# If we are here nothing good happened. # If we are here nothing good happened.
msg = _('Unable to extend volume %s') % volume_name msg = _('Unable to extend volume %s') % volume_name
raise exception.VolumeBackendAPIException(data=msg) raise exception.VolumeBackendAPIException(data=msg)
@ -574,27 +577,25 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
def _update_volume_stats(self): def _update_volume_stats(self):
"""Retrieve stats info from volume group.""" """Retrieve stats info from volume group."""
with self._client.open_connection() as api: with self._client.open_connection() as api:
storageusage = api.get_storage_usage() if api.find_sc() else None storageusage = api.get_storage_usage()
if not storageusage:
msg = _('Unable to retrieve volume stats.')
raise exception.VolumeBackendAPIException(message=msg)
# all of this is basically static for now # all of this is basically static for now
data = {} data = {}
data['volume_backend_name'] = self.backend_name data['volume_backend_name'] = self.backend_name
data['vendor_name'] = 'Dell' data['vendor_name'] = 'Dell'
data['driver_version'] = self.VERSION data['driver_version'] = self.VERSION
data['storage_protocol'] = 'iSCSI' data['storage_protocol'] = self.storage_protocol
data['reserved_percentage'] = 0 data['reserved_percentage'] = 0
data['free_capacity_gb'] = 'unavailable'
data['total_capacity_gb'] = 'unavailable'
data['consistencygroup_support'] = True data['consistencygroup_support'] = True
# In theory if storageusage is None then we should have totalcapacity = storageusage.get('availableSpace')
# blown up getting it. If not just report unavailable. totalcapacitygb = self._bytes_to_gb(totalcapacity)
if storageusage is not None: data['total_capacity_gb'] = totalcapacitygb
totalcapacity = storageusage.get('availableSpace') freespace = storageusage.get('freeSpace')
totalcapacitygb = self._bytes_to_gb(totalcapacity) freespacegb = self._bytes_to_gb(freespace)
data['total_capacity_gb'] = totalcapacitygb data['free_capacity_gb'] = freespacegb
freespace = storageusage.get('freeSpace')
freespacegb = self._bytes_to_gb(freespace)
data['free_capacity_gb'] = freespacegb
data['QoS_support'] = False data['QoS_support'] = False
data['replication_enabled'] = self.replication_enabled data['replication_enabled'] = self.replication_enabled
if self.replication_enabled: if self.replication_enabled:
@ -627,22 +628,24 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
# volume to the original volume name. # volume to the original volume name.
original_volume_name = volume.get('id') original_volume_name = volume.get('id')
current_name = new_volume.get('id') current_name = new_volume.get('id')
# We should have this. If we don't we'll set it below.
provider_id = new_volume.get('provider_id')
LOG.debug('update_migrated_volume: %(current)s to %(original)s', LOG.debug('update_migrated_volume: %(current)s to %(original)s',
{'current': current_name, {'current': current_name,
'original': original_volume_name}) 'original': original_volume_name})
if original_volume_name: if original_volume_name:
with self._client.open_connection() as api: with self._client.open_connection() as api:
if api.find_sc(): scvolume = api.find_volume(current_name, provider_id)
scvolume = api.find_volume(current_name) if (scvolume and
if (scvolume and api.rename_volume(scvolume, original_volume_name)):
api.rename_volume(scvolume, original_volume_name)): # Replicate if we are supposed to.
# Replicate if we are supposed to. model_update = self._create_replications(api,
model_update = self._create_replications(api, new_volume,
new_volume, scvolume)
scvolume) model_update['_name_id'] = None
model_update['_name_id'] = None model_update['provider_id'] = scvolume['instanceId']
return model_update return model_update
# The world was horrible to us so we should error and leave. # The world was horrible to us so we should error and leave.
LOG.error(_LE('Unable to rename the logical volume for volume: %s'), LOG.error(_LE('Unable to rename the logical volume for volume: %s'),
original_volume_name) original_volume_name)
@ -1072,17 +1075,25 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
for volume in volumes: for volume in volumes:
model_update = {} model_update = {}
if volume.get('replication_driver_data'): if volume.get('replication_driver_data'):
ret = api.break_replication(volume['id'], destssn) rvol = api.break_replication(
LOG.info(_LI('Failing over volume %(id)s ' volume['id'], volume.get('provider_id'),
'replication: %(res)s.'), destssn)
{'id': volume['id'], if rvol:
'res': ('FAILED', 'SUCCESS')[ret]}) LOG.info(_LI('Success failing over volume %s'),
# We should note that we are now failed over. volume['id'])
else:
LOG.info(_LI('Failed failing over volume %s'),
volume['id'])
# We should note that we are now failed over
# and that we have a new instanceId.
model_update = { model_update = {
'replication_status': 'failed-over'} 'replication_status': 'failed-over',
'provider_id': rvol['instanceId']}
else: else:
# Not a replicated volume. Try to unmap it. # Not a replicated volume. Try to unmap it.
scvolume = api.find_volume(volume['id']) scvolume = api.find_volume(
volume['id'], volume.get('provider_id'))
api.remove_mappings(scvolume) api.remove_mappings(scvolume)
model_update = {'status': 'error'} model_update = {'status': 'error'}
# Either we are failed over or our status is now error. # Either we are failed over or our status is now error.
@ -1152,10 +1163,10 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
backend storage object, raise a ManageExistingInvalidReference backend storage object, raise a ManageExistingInvalidReference
exception. exception.
""" """
volume_name = snapshot.get('volume_id')
snapshot_id = snapshot.get('id')
with self._client.open_connection() as api: with self._client.open_connection() as api:
# Find our unmanaged snapshot. This will raise on error. # Find our unmanaged snapshot. This will raise on error.
volume_name = snapshot.get('volume_id')
snapshot_id = snapshot.get('id')
screplay = self._get_unmanaged_replay(api, volume_name, screplay = self._get_unmanaged_replay(api, volume_name,
existing_ref) existing_ref)
# Manage means update description and update expiration. # Manage means update description and update expiration.
@ -1175,6 +1186,7 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
{'exist': screplay.get('description'), {'exist': screplay.get('description'),
'volume': volume_name, 'volume': volume_name,
'id': snapshot_id}) 'id': snapshot_id})
return {'provider_id': screplay['createVolume']['instanceId']}
# NOTE: Can't use abstractmethod before all drivers implement it # NOTE: Can't use abstractmethod before all drivers implement it
def manage_existing_snapshot_get_size(self, snapshot, existing_ref): def manage_existing_snapshot_get_size(self, snapshot, existing_ref):
@ -1202,11 +1214,13 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD,
NOTE: We do set the expire countdown to 1 day. Once a snapshot is NOTE: We do set the expire countdown to 1 day. Once a snapshot is
unmanaged it will expire 24 hours later. unmanaged it will expire 24 hours later.
""" """
volume_name = snapshot.get('volume_id')
snapshot_id = snapshot.get('id')
with self._client.open_connection() as api: with self._client.open_connection() as api:
snapshot_id = snapshot.get('id')
# provider_id is the snapshot's parent volume's instanceId.
provider_id = snapshot.get('provider_id')
volume_name = snapshot.get('volume_id')
# Find our volume. # Find our volume.
scvolume = api.find_volume(volume_name) scvolume = api.find_volume(volume_name, provider_id)
if not scvolume: if not scvolume:
# Didn't find it. # Didn't find it.
msg = (_('unmanage_snapshot: Cannot find volume id %s') msg = (_('unmanage_snapshot: Cannot find volume id %s')

View File

@ -47,14 +47,16 @@ class DellStorageCenterFCDriver(dell_storagecenter_common.DellCommonDriver,
2.4.0 - Added Replication V2 support. 2.4.0 - Added Replication V2 support.
2.4.1 - Updated Replication support to V2.1. 2.4.1 - Updated Replication support to V2.1.
2.5.0 - ManageableSnapshotsVD implemented. 2.5.0 - ManageableSnapshotsVD implemented.
3.0.0 - ProviderID utilized.
""" """
VERSION = '2.5.0' VERSION = '3.0.0'
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(DellStorageCenterFCDriver, self).__init__(*args, **kwargs) super(DellStorageCenterFCDriver, self).__init__(*args, **kwargs)
self.backend_name =\ self.backend_name =\
self.configuration.safe_get('volume_backend_name') or 'Dell-FC' self.configuration.safe_get('volume_backend_name') or 'Dell-FC'
self.storage_protocol = 'FC'
@fczm_utils.AddFCZone @fczm_utils.AddFCZone
def initialize_connection(self, volume, connector): def initialize_connection(self, volume, connector):
@ -71,10 +73,12 @@ class DellStorageCenterFCDriver(dell_storagecenter_common.DellCommonDriver,
# We use id to name the volume name as it is a # We use id to name the volume name as it is a
# known unique name. # known unique name.
volume_name = volume.get('id') volume_name = volume.get('id')
provider_id = volume.get('provider_id')
LOG.debug('Initialize connection: %s', volume_name) LOG.debug('Initialize connection: %s', volume_name)
with self._client.open_connection() as api: with self._client.open_connection() as api:
try: try:
# Find our server. # Find our server.
scserver = None
wwpns = connector.get('wwpns') wwpns = connector.get('wwpns')
for wwn in wwpns: for wwn in wwpns:
scserver = api.find_server(wwn) scserver = api.find_server(wwn)
@ -85,14 +89,13 @@ class DellStorageCenterFCDriver(dell_storagecenter_common.DellCommonDriver,
if scserver is None: if scserver is None:
scserver = api.create_server_multiple_hbas(wwpns) scserver = api.create_server_multiple_hbas(wwpns)
# Find the volume on the storage center. # Find the volume on the storage center.
scvolume = api.find_volume(volume_name) scvolume = api.find_volume(volume_name, provider_id)
if scserver is not None and scvolume is not None: if scserver is not None and scvolume is not None:
mapping = api.map_volume(scvolume, mapping = api.map_volume(scvolume, scserver)
scserver)
if mapping is not None: if mapping is not None:
# Since we just mapped our volume we had best update # Since we just mapped our volume we had best update
# our sc volume object. # our sc volume object.
scvolume = api.find_volume(volume_name) scvolume = api.get_volume(scvolume['instanceId'])
lun, targets, init_targ_map = api.find_wwns(scvolume, lun, targets, init_targ_map = api.find_wwns(scvolume,
scserver) scserver)
if lun is not None and len(targets) > 0: if lun is not None and len(targets) > 0:
@ -118,9 +121,11 @@ class DellStorageCenterFCDriver(dell_storagecenter_common.DellCommonDriver,
def terminate_connection(self, volume, connector, force=False, **kwargs): def terminate_connection(self, volume, connector, force=False, **kwargs):
# Get our volume name # Get our volume name
volume_name = volume.get('id') volume_name = volume.get('id')
provider_id = volume.get('provider_id')
LOG.debug('Terminate connection: %s', volume_name) LOG.debug('Terminate connection: %s', volume_name)
with self._client.open_connection() as api: with self._client.open_connection() as api:
try: try:
scserver = None
wwpns = connector.get('wwpns') wwpns = connector.get('wwpns')
for wwn in wwpns: for wwn in wwpns:
scserver = api.find_server(wwn) scserver = api.find_server(wwn)
@ -128,10 +133,9 @@ class DellStorageCenterFCDriver(dell_storagecenter_common.DellCommonDriver,
break break
# Find the volume on the storage center. # Find the volume on the storage center.
scvolume = api.find_volume(volume_name) scvolume = api.find_volume(volume_name, provider_id)
# Get our target map so we can return it to free up a zone. # Get our target map so we can return it to free up a zone.
lun, targets, init_targ_map = api.find_wwns(scvolume, lun, targets, init_targ_map = api.find_wwns(scvolume, scserver)
scserver)
# If we have a server and a volume lets unmap them. # If we have a server and a volume lets unmap them.
if (scserver is not None and if (scserver is not None and
scvolume is not None and scvolume is not None and
@ -157,15 +161,3 @@ class DellStorageCenterFCDriver(dell_storagecenter_common.DellCommonDriver,
LOG.error(_LE('Failed to terminate connection')) LOG.error(_LE('Failed to terminate connection'))
raise exception.VolumeBackendAPIException( raise exception.VolumeBackendAPIException(
_('Terminate connection unable to connect to backend.')) _('Terminate connection unable to connect to backend.'))
def get_volume_stats(self, refresh=False):
"""Get volume status.
If 'refresh' is True, run update the stats first.
"""
if refresh:
self._update_volume_stats()
# Update our protocol to the correct one.
self._stats['storage_protocol'] = 'FC'
return self._stats

View File

@ -46,9 +46,10 @@ class DellStorageCenterISCSIDriver(dell_storagecenter_common.DellCommonDriver,
2.4.0 - Added Replication V2 support. 2.4.0 - Added Replication V2 support.
2.4.1 - Updated Replication support to V2.1. 2.4.1 - Updated Replication support to V2.1.
2.5.0 - ManageableSnapshotsVD implemented. 2.5.0 - ManageableSnapshotsVD implemented.
3.0.0 - ProviderID utilized.
""" """
VERSION = '2.5.0' VERSION = '3.0.0'
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(DellStorageCenterISCSIDriver, self).__init__(*args, **kwargs) super(DellStorageCenterISCSIDriver, self).__init__(*args, **kwargs)
@ -72,6 +73,7 @@ class DellStorageCenterISCSIDriver(dell_storagecenter_common.DellCommonDriver,
# We use id to name the volume name as it is a # We use id to name the volume name as it is a
# known unique name. # known unique name.
volume_name = volume.get('id') volume_name = volume.get('id')
provider_id = volume.get('provider_id')
initiator_name = connector.get('initiator') initiator_name = connector.get('initiator')
multipath = connector.get('multipath', False) multipath = connector.get('multipath', False)
LOG.info(_LI('initialize_ connection: %(vol)s:%(initiator)s'), LOG.info(_LI('initialize_ connection: %(vol)s:%(initiator)s'),
@ -86,7 +88,7 @@ class DellStorageCenterISCSIDriver(dell_storagecenter_common.DellCommonDriver,
if server is None: if server is None:
server = api.create_server(initiator_name) server = api.create_server(initiator_name)
# Find the volume on the storage center. # Find the volume on the storage center.
scvolume = api.find_volume(volume_name) scvolume = api.find_volume(volume_name, provider_id)
# if we have a server and a volume lets bring them together. # if we have a server and a volume lets bring them together.
if server is not None and scvolume is not None: if server is not None and scvolume is not None:
@ -95,7 +97,7 @@ class DellStorageCenterISCSIDriver(dell_storagecenter_common.DellCommonDriver,
if mapping is not None: if mapping is not None:
# Since we just mapped our volume we had best update # Since we just mapped our volume we had best update
# our sc volume object. # our sc volume object.
scvolume = api.find_volume(volume_name) scvolume = api.get_volume(provider_id)
# Our return. # Our return.
iscsiprops = {} iscsiprops = {}
ip = None ip = None
@ -146,6 +148,7 @@ class DellStorageCenterISCSIDriver(dell_storagecenter_common.DellCommonDriver,
# Grab some initial info. # Grab some initial info.
initiator_name = connector.get('initiator') initiator_name = connector.get('initiator')
volume_name = volume.get('id') volume_name = volume.get('id')
provider_id = volume.get('provider_id')
LOG.debug('Terminate connection: %(vol)s:%(initiator)s', LOG.debug('Terminate connection: %(vol)s:%(initiator)s',
{'vol': volume_name, {'vol': volume_name,
'initiator': initiator_name}) 'initiator': initiator_name})
@ -153,7 +156,7 @@ class DellStorageCenterISCSIDriver(dell_storagecenter_common.DellCommonDriver,
try: try:
scserver = api.find_server(initiator_name) scserver = api.find_server(initiator_name)
# Find the volume on the storage center. # Find the volume on the storage center.
scvolume = api.find_volume(volume_name) scvolume = api.find_volume(volume_name, provider_id)
# If we have a server and a volume lets pull them apart. # If we have a server and a volume lets pull them apart.
if (scserver is not None and if (scserver is not None and