]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Dell SC driver honoring folder name after volume creation.
authorTom Swanson <tom_swanson@dell.com>
Mon, 27 Apr 2015 22:33:40 +0000 (17:33 -0500)
committerTom Swanson <tom_swanson@dell.com>
Tue, 12 May 2015 17:42:09 +0000 (12:42 -0500)
The Dell SC driver was not honoring the volume folder name
after creation.  This has been changed so that find_volume
now checks the dell_sc_volume_folder for the requested volume
before doing a general search of the storage center.  In
either case if more than one volume is returned (two in
the dell_sc_volume_folder or two outside of that folder) then
an exception is thrown.

Also the dell_sc_volume_folder, dell_sc_server_folder and
dell_sc_ssn variables are no longer being passed arond.  They
are saved as part of the backend API object.

Tests have been updated.

Change-Id: I962ea3ed262d21deff65cdc8476939aab6ba07e2
Closes-Bug: #1449290

cinder/tests/unit/test_dellfc.py
cinder/tests/unit/test_dellsc.py
cinder/tests/unit/test_dellscapi.py
cinder/volume/drivers/dell/dell_storagecenter_api.py
cinder/volume/drivers/dell/dell_storagecenter_common.py
cinder/volume/drivers/dell/dell_storagecenter_fc.py
cinder/volume/drivers/dell/dell_storagecenter_iscsi.py

index cf16e5b132d170830be4339991b2587ba9913d73..99aedc92af86cb57feb4ee5af7e5192163fa4f18 100644 (file)
@@ -207,10 +207,20 @@ class DellSCSanFCDriverTestCase(test.TestCase):
                                    mock_init):
         volume = {'id': self.volume_name}
         connector = self.connector
-        data = self.driver.initialize_connection(volume, connector)
-        self.assertEqual(data['driver_volume_type'], 'fibre_channel')
+        res = self.driver.initialize_connection(volume, connector)
+        expected = {'data':
+                    {'initiator_target_map':
+                     {u'21000024FF30441C': [u'5000D31000FCBE35'],
+                      u'21000024FF30441D': [u'5000D31000FCBE3D']},
+                     'target_discovered': True,
+                     'target_lun': 1,
+                     'target_wwn':
+                     [u'5000D31000FCBE3D', u'5000D31000FCBE35']},
+                    'driver_volume_type': 'fibre_channel'}
+
+        self.assertEqual(expected, res, 'Unexpected return data')
         # verify find_volume has been called and that is has been called twice
-        mock_find_volume.assert_any_call(64702, self.volume_name)
+        mock_find_volume.assert_any_call(self.volume_name)
         assert mock_find_volume.call_count == 2
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@@ -378,8 +388,11 @@ class DellSCSanFCDriverTestCase(test.TestCase):
                                   mock_init):
         volume = {'id': self.volume_name}
         connector = self.connector
-        self.driver.terminate_connection(volume, connector)
+        res = self.driver.terminate_connection(volume, connector)
         mock_unmap_volume.assert_called_once_with(self.VOLUME, self.SCSERVER)
+        expected = {'driver_volume_type': 'fibre_channel',
+                    'data': {}}
+        self.assertEqual(expected, res, 'Unexpected return data')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        'find_sc',
@@ -499,7 +512,10 @@ class DellSCSanFCDriverTestCase(test.TestCase):
         #                  self.driver.terminate_connection,
         #                  volume,
         #                  connector)
-        self.driver.terminate_connection(volume, connector)
+        res = self.driver.terminate_connection(volume, connector)
+        expected = {'driver_volume_type': 'fibre_channel',
+                    'data': {}}
+        self.assertEqual(expected, res, 'Unexpected return data')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        'find_sc',
@@ -542,6 +558,54 @@ class DellSCSanFCDriverTestCase(test.TestCase):
                           volume,
                           connector)
 
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       'find_sc',
+                       return_value=64702)
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       'find_server',
+                       return_value=SCSERVER)
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       'find_volume',
+                       return_value=VOLUME)
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       'unmap_volume',
+                       return_value=True)
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       'find_wwns',
+                       return_value=(1,
+                                     [u'5000D31000FCBE3D',
+                                      u'5000D31000FCBE35'],
+                                     {u'21000024FF30441C':
+                                      [u'5000D31000FCBE35'],
+                                      u'21000024FF30441D':
+                                      [u'5000D31000FCBE3D']}))
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       'get_volume_count',
+                       return_value=0)
+    def test_terminate_connection_vol_count_zero(self,
+                                                 mock_get_volume_count,
+                                                 mock_find_wwns,
+                                                 mock_unmap_volume,
+                                                 mock_find_volume,
+                                                 mock_find_server,
+                                                 mock_find_sc,
+                                                 mock_close_connection,
+                                                 mock_open_connection,
+                                                 mock_init):
+        # Test case where get_volume_count is zero
+        volume = {'id': self.volume_name}
+        connector = self.connector
+        res = self.driver.terminate_connection(volume, connector)
+        mock_unmap_volume.assert_called_once_with(self.VOLUME, self.SCSERVER)
+        expected = {'data':
+                    {'initiator_target_map':
+                     {u'21000024FF30441C': [u'5000D31000FCBE35'],
+                      u'21000024FF30441D': [u'5000D31000FCBE3D']},
+                     'target_wwn':
+                     [u'5000D31000FCBE3D', u'5000D31000FCBE35']},
+                    'driver_volume_type': 'fibre_channel'}
+        self.assertEqual(expected, res, 'Unexpected return data')
+
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        'find_sc',
                        return_value=64702)
index 3a9b4f2ab58b2ed962f6b43e69c5f1644397a48c..045f7b124bfd41a32b0919f81a7973109e329ea3 100644 (file)
@@ -273,9 +273,7 @@ class DellSCSanISCSIDriverTestCase(test.TestCase):
         volume = {'id': self.volume_name, 'size': 1}
         self.driver.create_volume(volume)
         mock_create_volume.assert_called_once_with(self.volume_name,
-                                                   1,
-                                                   12345,
-                                                   u'opnstktst')
+                                                   1)
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        'create_volume',
@@ -307,7 +305,7 @@ class DellSCSanISCSIDriverTestCase(test.TestCase):
                            mock_init):
         volume = {'id': self.volume_name, 'size': 1}
         self.driver.delete_volume(volume)
-        mock_delete_volume.assert_called_once_with(12345, self.volume_name)
+        mock_delete_volume.assert_called_once_with(self.volume_name)
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        'delete_volume',
@@ -359,7 +357,7 @@ class DellSCSanISCSIDriverTestCase(test.TestCase):
         data = self.driver.initialize_connection(volume, connector)
         self.assertEqual(data['driver_volume_type'], 'iscsi')
         # verify find_volume has been called and that is has been called twice
-        mock_find_volume.assert_any_call(12345, self.volume_name)
+        mock_find_volume.assert_any_call(self.volume_name)
         assert mock_find_volume.call_count == 2
         expected = {'data':
                     {'access_mode': 'rw',
@@ -406,7 +404,7 @@ class DellSCSanISCSIDriverTestCase(test.TestCase):
         data = self.driver.initialize_connection(volume, connector)
         self.assertEqual(data['driver_volume_type'], 'iscsi')
         # verify find_volume has been called and that is has been called twice
-        mock_find_volume.assert_any_call(12345, self.volume_name)
+        mock_find_volume.assert_any_call(self.volume_name)
         assert mock_find_volume.call_count == 2
         expected = {'data':
                     {'access_mode': 'rw',
@@ -573,8 +571,9 @@ class DellSCSanISCSIDriverTestCase(test.TestCase):
                                   mock_init):
         volume = {'id': self.volume_name}
         connector = self.connector
-        self.driver.terminate_connection(volume, connector)
+        res = self.driver.terminate_connection(volume, connector)
         mock_unmap_volume.assert_called_once_with(self.VOLUME, self.SCSERVER)
+        self.assertIsNone(res, 'None expected')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        'find_sc',
@@ -823,7 +822,6 @@ class DellSCSanISCSIDriverTestCase(test.TestCase):
         self.driver.create_cloned_volume(volume, src_vref)
         mock_create_cloned_volume. \
             assert_called_once_with(self.volume_name + '_clone',
-                                    self.configuration.dell_sc_volume_folder,
                                     self.VOLUME)
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@@ -912,7 +910,7 @@ class DellSCSanISCSIDriverTestCase(test.TestCase):
         volume = {'id': self.VOLUME.get(u'name')}
         self.driver.ensure_export(context, volume)
         mock_find_volume.assert_called_once_with(
-            12345, self.VOLUME.get(u'name'))
+            self.VOLUME.get(u'name'))
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        'find_sc',
index 6fe4326137ff3ea08f2853e427d0a2dd46ed9f14..31b36b1542c389c6119d683de9012891c5e2d8cd 100644 (file)
@@ -110,6 +110,124 @@ class DellSCSanAPITestCase(test.TestCase):
               u'mapped': False,
               u'cmmSource': False}
 
+    VOLUME_LIST = [{u'instanceId': u'64702.3494',
+                    u'scSerialNumber': 64702,
+                    u'replicationSource': False,
+                    u'liveVolume': False,
+                    u'vpdId': 3496,
+                    u'objectType': u'ScVolume',
+                    u'index': 3494,
+                    u'volumeFolderPath': u'devstackvol/fcvm/',
+                    u'hostCacheEnabled': False,
+                    u'usedByLegacyFluidFsNasVolume': False,
+                    u'inRecycleBin': False,
+                    u'volumeFolderIndex': 17,
+                    u'instanceName':
+                        u'volume-37883deb-85cd-426a-9a98-62eaad8671ea',
+                    u'statusMessage': u'',
+                    u'status': u'Up',
+                    u'storageType': {u'instanceId': u'64702.1',
+                                     u'instanceName':
+                                     u'Assigned - Redundant - 2 MB',
+                                     u'objectType': u'ScStorageType'},
+                    u'cmmDestination': False,
+                    u'replicationDestination': False,
+                    u'volumeFolder': {u'instanceId': u'64702.17',
+                                      u'instanceName': u'fcvm',
+                                      u'objectType': u'ScVolumeFolder'},
+                    u'deviceId': u'6000d31000fcbe000000000000000da8',
+                    u'active': True,
+                    u'portableVolumeDestination': False,
+                    u'deleteAllowed': True,
+                    u'name': u'volume-37883deb-85cd-426a-9a98-62eaad8671ea',
+                    u'scName': u'Storage Center 64702',
+                    u'secureDataUsed': False,
+                    u'serialNumber': u'0000fcbe-00000da8',
+                    u'replayAllowed': True,
+                    u'flashOptimized': False,
+                    u'configuredSize': u'1.073741824E9 Bytes',
+                    u'mapped': False,
+                    u'cmmSource': False}]
+
+    # Volume list that contains multiple volumes
+    VOLUME_LIST_MULTI_VOLS = [
+        {u'instanceId': u'64702.3494',
+         u'scSerialNumber': 64702,
+         u'replicationSource': False,
+         u'liveVolume': False,
+         u'vpdId': 3496,
+         u'objectType': u'ScVolume',
+         u'index': 3494,
+         u'volumeFolderPath': u'devstackvol/fcvm/',
+         u'hostCacheEnabled': False,
+         u'usedByLegacyFluidFsNasVolume': False,
+         u'inRecycleBin': False,
+         u'volumeFolderIndex': 17,
+         u'instanceName':
+                        u'volume-37883deb-85cd-426a-9a98-62eaad8671ea',
+         u'statusMessage': u'',
+         u'status': u'Up',
+                    u'storageType': {u'instanceId': u'64702.1',
+                                     u'instanceName':
+                                     u'Assigned - Redundant - 2 MB',
+                                     u'objectType': u'ScStorageType'},
+                    u'cmmDestination': False,
+                    u'replicationDestination': False,
+                    u'volumeFolder': {u'instanceId': u'64702.17',
+                                      u'instanceName': u'fcvm',
+                                      u'objectType': u'ScVolumeFolder'},
+                    u'deviceId': u'6000d31000fcbe000000000000000da8',
+                    u'active': True,
+                    u'portableVolumeDestination': False,
+                    u'deleteAllowed': True,
+                    u'name': u'volume-37883deb-85cd-426a-9a98-62eaad8671ea',
+                    u'scName': u'Storage Center 64702',
+                    u'secureDataUsed': False,
+                    u'serialNumber': u'0000fcbe-00000da8',
+                    u'replayAllowed': True,
+                    u'flashOptimized': False,
+                    u'configuredSize': u'1.073741824E9 Bytes',
+                    u'mapped': False,
+                    u'cmmSource': False},
+        {u'instanceId': u'64702.3495',
+         u'scSerialNumber': 64702,
+         u'replicationSource': False,
+         u'liveVolume': False,
+         u'vpdId': 3496,
+         u'objectType': u'ScVolume',
+         u'index': 3495,
+         u'volumeFolderPath': u'devstackvol/fcvm/',
+         u'hostCacheEnabled': False,
+         u'usedByLegacyFluidFsNasVolume': False,
+         u'inRecycleBin': False,
+         u'volumeFolderIndex': 17,
+         u'instanceName':
+         u'volume-37883deb-85cd-426a-9a98-62eaad8671ea',
+         u'statusMessage': u'',
+         u'status': u'Up',
+         u'storageType': {u'instanceId': u'64702.1',
+                          u'instanceName':
+                          u'Assigned - Redundant - 2 MB',
+                          u'objectType': u'ScStorageType'},
+         u'cmmDestination': False,
+         u'replicationDestination': False,
+         u'volumeFolder': {u'instanceId': u'64702.17',
+                           u'instanceName': u'fcvm',
+                           u'objectType': u'ScVolumeFolder'},
+         u'deviceId': u'6000d31000fcbe000000000000000da9',
+         u'active': True,
+         u'portableVolumeDestination': False,
+         u'deleteAllowed': True,
+         u'name': u'volume-37883deb-85cd-426a-9a98-62eaad8671ea',
+         u'scName': u'Storage Center 64702',
+         u'secureDataUsed': False,
+         u'serialNumber': u'0000fcbe-00000da8',
+         u'replayAllowed': True,
+         u'flashOptimized': False,
+         u'configuredSize': u'1.073741824E9 Bytes',
+         u'mapped': False,
+         u'cmmSource': False}]
+
     VOLUME_CONFIG = \
         {u'instanceId': u'64702.3494',
          u'scSerialNumber': 64702,
@@ -1328,6 +1446,11 @@ class DellSCSanAPITestCase(test.TestCase):
             self.configuration.san_login,
             self.configuration.san_password)
 
+        # Set up the scapi configuration vars
+        self.scapi.ssn = self.configuration.dell_sc_ssn
+        self.scapi.sfname = self.configuration.dell_sc_server_folder
+        self.scapi.vfname = self.configuration.dell_sc_volume_folder
+
         self.volid = str(uuid.uuid4())
         self.volume_name = "volume" + self.volid
 
@@ -1351,7 +1474,7 @@ class DellSCSanAPITestCase(test.TestCase):
                      mock_close_connection,
                      mock_open_connection,
                      mock_init):
-        res = self.scapi.find_sc(64702)
+        res = self.scapi.find_sc()
         mock_get.assert_called_once_with('StorageCenter/StorageCenter')
         self.assertTrue(mock_get_result.called)
         self.assertEqual(u'64702', res, 'Unexpected SSN')
@@ -1369,7 +1492,7 @@ class DellSCSanAPITestCase(test.TestCase):
                              mock_open_connection,
                              mock_init):
         self.assertRaises(exception.VolumeBackendAPIException,
-                          self.scapi.find_sc, 12345)
+                          self.scapi.find_sc)
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_first_result',
@@ -1384,7 +1507,8 @@ class DellSCSanAPITestCase(test.TestCase):
                            mock_open_connection,
                            mock_init):
         res = self.scapi._create_folder(
-            'StorageCenter/ScVolumeFolder', 12345, '',
+            'StorageCenter/ScVolumeFolder',
+            '',
             self.configuration.dell_sc_volume_folder)
         self.assertTrue(mock_post.called)
         self.assertTrue(mock_first_result.called)
@@ -1404,7 +1528,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                        mock_init):
         # Test case where parent folder name is specified
         res = self.scapi._create_folder(
-            'StorageCenter/ScVolumeFolder', 12345, 'parentFolder',
+            'StorageCenter/ScVolumeFolder', 'parentFolder',
             self.configuration.dell_sc_volume_folder)
         self.assertTrue(mock_post.called)
         self.assertTrue(mock_first_result.called)
@@ -1419,7 +1543,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                    mock_open_connection,
                                    mock_init):
         res = self.scapi._create_folder(
-            'StorageCenter/ScVolumeFolder', 12345, '',
+            'StorageCenter/ScVolumeFolder', '',
             self.configuration.dell_sc_volume_folder)
         self.assertIsNone(res, 'Test Create folder - None expected')
 
@@ -1436,7 +1560,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                 mock_open_connection,
                                 mock_init):
         res = self.scapi._create_folder_path(
-            'StorageCenter/ScVolumeFolder', 12345,
+            'StorageCenter/ScVolumeFolder',
             self.configuration.dell_sc_volume_folder)
         mock_path_to_array.assert_called_once_with(
             self.configuration.dell_sc_volume_folder)
@@ -1461,7 +1585,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                             mock_init):
         # Test case where folder is not found and must be created
         res = self.scapi._create_folder_path(
-            'StorageCenter/ScVolumeFolder', 12345,
+            'StorageCenter/ScVolumeFolder',
             self.configuration.dell_sc_volume_folder)
         mock_path_to_array.assert_called_once_with(
             self.configuration.dell_sc_volume_folder)
@@ -1488,7 +1612,7 @@ class DellSCSanAPITestCase(test.TestCase):
         # Test case where folder is not found, must be created
         # and creation fails
         res = self.scapi._create_folder_path(
-            'StorageCenter/ScVolumeFolder', 12345,
+            'StorageCenter/ScVolumeFolder',
             self.configuration.dell_sc_volume_folder)
         mock_path_to_array.assert_called_once_with(
             self.configuration.dell_sc_volume_folder)
@@ -1509,7 +1633,7 @@ class DellSCSanAPITestCase(test.TestCase):
                          mock_open_connection,
                          mock_init):
         res = self.scapi._find_folder(
-            'StorageCenter/ScVolumeFolder', 12345,
+            'StorageCenter/ScVolumeFolder',
             self.configuration.dell_sc_volume_folder)
         self.assertTrue(mock_post.called)
         self.assertTrue(mock_get_result.called)
@@ -1529,7 +1653,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                     mock_init):
         # Test case for folder path with multiple folders
         res = self.scapi._find_folder(
-            'StorageCenter/ScVolumeFolder', 12345,
+            'StorageCenter/ScVolumeFolder',
             u'testParentFolder/opnstktst')
         self.assertTrue(mock_post.called)
         self.assertTrue(mock_get_result.called)
@@ -1544,26 +1668,25 @@ class DellSCSanAPITestCase(test.TestCase):
                                  mock_open_connection,
                                  mock_init):
         res = self.scapi._find_folder(
-            'StorageCenter/ScVolumeFolder', 12345,
+            'StorageCenter/ScVolumeFolder',
             self.configuration.dell_sc_volume_folder)
         self.assertIsNone(res, 'Test find folder - None expected')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_create_folder_path',
-                       return_value=FLDR)
-    def test_create_volume_folder_path(self,
-                                       mock_create_vol_fldr_path,
-                                       mock_close_connection,
-                                       mock_open_connection,
-                                       mock_init):
-        res = self.scapi._create_volume_folder_path(
-            12345,
-            self.configuration.dell_sc_volume_folder)
-        mock_create_vol_fldr_path.assert_called_once_with(
-            'StorageCenter/ScVolumeFolder',
-            12345,
+                       '_find_folder',
+                       return_value=None)
+    def test_find_volume_folder_fail(self,
+                                     mock_find_folder,
+                                     mock_close_connection,
+                                     mock_open_connection,
+                                     mock_init):
+        # Test case where _find_volume_folder returns none
+        res = self.scapi._find_volume_folder(
+            False)
+        mock_find_folder.assert_called_once_with(
+            'StorageCenter/ScVolumeFolder/GetList',
             self.configuration.dell_sc_volume_folder)
-        self.assertEqual(self.FLDR, res, 'Unexpected ScFolder')
+        self.assertIsNone(res, 'Expected None')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_find_folder',
@@ -1574,12 +1697,32 @@ class DellSCSanAPITestCase(test.TestCase):
                                 mock_open_connection,
                                 mock_init):
         res = self.scapi._find_volume_folder(
-            12345,
+            False)
+        mock_find_folder.assert_called_once_with(
+            'StorageCenter/ScVolumeFolder/GetList',
             self.configuration.dell_sc_volume_folder)
+        self.assertEqual(self.FLDR, res, 'Unexpected Folder')
+
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_create_folder_path',
+                       return_value=FLDR)
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_find_folder',
+                       return_value=None)
+    def test_find_volume_folder_create_folder(self,
+                                              mock_find_folder,
+                                              mock_create_folder_path,
+                                              mock_close_connection,
+                                              mock_open_connection,
+                                              mock_init):
+        # Test case where _find_volume_folder returns none and folder must be
+        # created
+        res = self.scapi._find_volume_folder(
+            True)
         mock_find_folder.assert_called_once_with(
             'StorageCenter/ScVolumeFolder/GetList',
-            12345,
             self.configuration.dell_sc_volume_folder)
+        self.assertTrue(mock_create_folder_path.called)
         self.assertEqual(self.FLDR, res, 'Unexpected Folder')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@@ -1661,56 +1804,46 @@ class DellSCSanAPITestCase(test.TestCase):
                            mock_init):
         res = self.scapi.create_volume(
             self.volume_name,
-            1,
-            12345,
-            self.configuration.dell_sc_volume_folder)
+            1)
         self.assertTrue(mock_post.called)
         self.assertTrue(mock_get_json.called)
-        mock_find_volume_folder.assert_called_once_with(
-            12345, self.configuration.dell_sc_volume_folder)
+        mock_find_volume_folder.assert_called_once_with(True)
         self.assertEqual(self.VOLUME, res, 'Unexpected ScVolume')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_get_json',
+                       'find_volume',
                        return_value=VOLUME)
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_create_volume_folder_path',
-                       return_value=FLDR)
+                       '_get_json',
+                       return_value=None)
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_find_volume_folder',
-                       return_value=None)
+                       return_value=FLDR)
     @mock.patch.object(dell_storagecenter_api.HttpClient,
                        'post',
                        return_value=RESPONSE_201)
-    def test_create_vol_and_folder(self,
-                                   mock_post,
-                                   mock_find_volume_folder,
-                                   mock_create_vol_folder_path,
-                                   mock_get_json,
-                                   mock_close_connection,
-                                   mock_open_connection,
-                                   mock_init):
-        # Test calling create_volume where volume folder has to be created
+    def test_create_volume_retry_find(self,
+                                      mock_post,
+                                      mock_find_volume_folder,
+                                      mock_get_json,
+                                      mock_find_volume,
+                                      mock_close_connection,
+                                      mock_open_connection,
+                                      mock_init):
+        # Test case where find_volume is used to do a retry of finding the
+        # created volume
         res = self.scapi.create_volume(
             self.volume_name,
-            1,
-            12345,
-            self.configuration.dell_sc_volume_folder)
+            1)
         self.assertTrue(mock_post.called)
         self.assertTrue(mock_get_json.called)
-        mock_create_vol_folder_path.assert_called_once_with(
-            12345,
-            self.configuration.dell_sc_volume_folder)
-        mock_find_volume_folder.assert_called_once_with(
-            12345, self.configuration.dell_sc_volume_folder)
+        self.assertTrue(mock_find_volume.called)
+        mock_find_volume_folder.assert_called_once_with(True)
         self.assertEqual(self.VOLUME, res, 'Unexpected ScVolume')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_get_json',
                        return_value=VOLUME)
-    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_create_volume_folder_path',
-                       return_value=None)
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_find_volume_folder',
                        return_value=None)
@@ -1720,7 +1853,6 @@ class DellSCSanAPITestCase(test.TestCase):
     def test_create_vol_folder_fail(self,
                                     mock_post,
                                     mock_find_volume_folder,
-                                    mock_create_vol_folder_path,
                                     mock_get_json,
                                     mock_close_connection,
                                     mock_open_connection,
@@ -1729,16 +1861,10 @@ class DellSCSanAPITestCase(test.TestCase):
         # fails to be created
         res = self.scapi.create_volume(
             self.volume_name,
-            1,
-            12345,
-            self.configuration.dell_sc_volume_folder)
+            1)
         self.assertTrue(mock_post.called)
         self.assertTrue(mock_get_json.called)
-        mock_create_vol_folder_path.assert_called_once_with(
-            12345,
-            self.configuration.dell_sc_volume_folder)
-        mock_find_volume_folder.assert_called_once_with(
-            12345, self.configuration.dell_sc_volume_folder)
+        mock_find_volume_folder.assert_called_once_with(True)
         self.assertEqual(self.VOLUME, res, 'Unexpected ScVolume')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@@ -1759,77 +1885,116 @@ class DellSCSanAPITestCase(test.TestCase):
                                    mock_init):
         res = self.scapi.create_volume(
             self.volume_name,
-            1,
-            12345,
-            self.configuration.dell_sc_volume_folder)
-        mock_find_volume_folder.assert_called_once_with(
-            12345, self.configuration.dell_sc_volume_folder)
+            1)
+        mock_find_volume_folder.assert_called_once_with(True)
         self.assertIsNone(res, 'None expected')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_first_result',
-                       return_value=VOLUME)
+                       '_get_json',
+                       return_value=VOLUME_LIST)
     @mock.patch.object(dell_storagecenter_api.HttpClient,
                        'post',
                        return_value=RESPONSE_200)
-    def test_find_volume_by_name(self,
-                                 mock_post,
-                                 mock_first_result,
-                                 mock_close_connection,
-                                 mock_open_connection,
-                                 mock_init):
-        # Test case to find volume by name
-        res = self.scapi.find_volume(12345,
-                                     self.volume_name)
+    def test__get_volume_list_enforce_vol_fldr(self,
+                                               mock_post,
+                                               mock_get_json,
+                                               mock_close_connection,
+                                               mock_open_connection,
+                                               mock_init):
+        # Test case to find volume in the configured volume folder
+        res = self.scapi._get_volume_list(self.volume_name, True)
         self.assertTrue(mock_post.called)
-        self.assertTrue(mock_first_result.called)
-        self.assertEqual(self.VOLUME, res, 'Unexpected volume')
+        self.assertTrue(mock_get_json.called)
+        self.assertEqual(self.VOLUME_LIST, res, 'Unexpected volume list')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_first_result',
-                       return_value=VOLUME)
+                       '_get_json',
+                       return_value=VOLUME_LIST)
     @mock.patch.object(dell_storagecenter_api.HttpClient,
                        'post',
                        return_value=RESPONSE_200)
-    # Test case to find volume by InstancedId
-    def test_find_volume_by_instanceid(self,
+    def test__get_volume_list_any_fldr(self,
                                        mock_post,
-                                       mock_first_result,
+                                       mock_get_json,
                                        mock_close_connection,
                                        mock_open_connection,
                                        mock_init):
-        res = self.scapi.find_volume(12345,
-                                     None,
-                                     '64702.3494')
+        # Test case to find volume anywhere in the configured SC
+        res = self.scapi._get_volume_list(self.volume_name, False)
         self.assertTrue(mock_post.called)
-        self.assertTrue(mock_first_result.called)
+        self.assertTrue(mock_get_json.called)
+        self.assertEqual(self.VOLUME_LIST, res, 'Unexpected volume list')
+
+    def test__get_volume_list_no_name(self,
+                                      mock_close_connection,
+                                      mock_open_connection,
+                                      mock_init):
+        # Test case specified volume name is None
+        res = self.scapi._get_volume_list(None, True)
+        self.assertIsNone(res, 'None expected')
+
+    @mock.patch.object(dell_storagecenter_api.HttpClient,
+                       'post',
+                       return_value=RESPONSE_204)
+    def test__get_volume_list_failure(self,
+                                      mock_post,
+                                      mock_close_connection,
+                                      mock_open_connection,
+                                      mock_init):
+        # Test case to find volume in the configured volume folder
+        res = self.scapi._get_volume_list(self.volume_name, True)
+        self.assertTrue(mock_post.called)
+        self.assertIsNone(res, 'None expected')
+
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_get_volume_list',
+                       return_value=VOLUME_LIST)
+    def test_find_volume(self,
+                         mock_get_vol_list,
+                         mock_close_connection,
+                         mock_open_connection,
+                         mock_init):
+        # Test case to find volume by name
+        res = self.scapi.find_volume(self.volume_name)
+        self.assertTrue(mock_get_vol_list.called)
         self.assertEqual(self.VOLUME, res, 'Unexpected volume')
 
-    def test_find_volume_no_name_or_instance(self,
-                                             mock_close_connection,
-                                             mock_open_connection,
-                                             mock_init):
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_get_volume_list',
+                       return_value=None)
+    def test_find_volume_no_name(self,
+                                 mock_get_volume_list,
+                                 mock_close_connection,
+                                 mock_open_connection,
+                                 mock_init):
         # Test calling find_volume with no name or instanceid
-        res = self.scapi.find_volume(12345)
+        res = self.scapi.find_volume(None)
         self.assertEqual(res, None, 'Expected None')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_first_result',
-                       return_value=None)
-    @mock.patch.object(dell_storagecenter_api.HttpClient,
-                       'post',
-                       return_value=RESPONSE_204)
+                       '_get_volume_list')
     def test_find_volume_not_found(self,
-                                   mock_post,
-                                   mock_first_result,
+                                   mock_get_volume_list,
                                    mock_close_connection,
                                    mock_open_connection,
                                    mock_init):
         # Test calling find_volume with result of no volume found
-        res = self.scapi.find_volume(12345,
-                                     self.volume_name)
+        mock_get_volume_list.side_effect = [[], []]
+        res = self.scapi.find_volume(self.volume_name)
         self.assertEqual(None, res, 'None expected')
 
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_get_volume_list',
+                       return_value=VOLUME_LIST_MULTI_VOLS)
+    def test_find_volume_multi_vols_found(self,
+                                          mock_get_volume_list,
+                                          mock_close_connection,
+                                          mock_open_connection,
+                                          mock_init):
+        # Test case where multiple volumes are found
+        self.assertRaises(exception.VolumeBackendAPIException,
+                          self.scapi.find_volume, self.volume_name)
+
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_get_json',
                        return_value=True)
@@ -1846,10 +2011,9 @@ class DellSCSanAPITestCase(test.TestCase):
                            mock_close_connection,
                            mock_open_connection,
                            mock_init):
-        res = self.scapi.delete_volume(12345,
-                                       self.volume_name)
+        res = self.scapi.delete_volume(self.volume_name)
         self.assertTrue(mock_delete.called)
-        mock_find_volume.assert_called_once_with(12345, self.volume_name, None)
+        mock_find_volume.assert_called_once_with(self.volume_name)
         self.assertTrue(mock_get_json.called)
         self.assertTrue(res)
 
@@ -1866,7 +2030,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                    mock_open_connection,
                                    mock_init):
         self.assertRaises(exception.VolumeBackendAPIException,
-                          self.scapi.delete_volume, 12345, self.volume_name)
+                          self.scapi.delete_volume, self.volume_name)
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        'find_volume',
@@ -1877,27 +2041,9 @@ class DellSCSanAPITestCase(test.TestCase):
                                         mock_open_connection,
                                         mock_init):
         # Test case where volume to be deleted does not exist
-        res = self.scapi.delete_volume(12345,
-                                       self.volume_name)
+        res = self.scapi.delete_volume(self.volume_name)
         self.assertTrue(res, 'Expected True')
 
-    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_create_folder_path',
-                       return_value=SVR_FLDR)
-    def test_create_server_folder_path(self,
-                                       mock_create_svr_fldr_path,
-                                       mock_close_connection,
-                                       mock_open_connection,
-                                       mock_init):
-        res = self.scapi._create_server_folder_path(
-            12345,
-            self.configuration.dell_sc_server_folder)
-        mock_create_svr_fldr_path.assert_called_once_with(
-            'StorageCenter/ScServerFolder',
-            12345,
-            self.configuration.dell_sc_server_folder)
-        self.assertEqual(self.SVR_FLDR, res, 'Unexpected server folder')
-
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_find_folder',
                        return_value=SVR_FLDR)
@@ -1906,15 +2052,49 @@ class DellSCSanAPITestCase(test.TestCase):
                                 mock_close_connection,
                                 mock_open_connection,
                                 mock_init):
-        res = self.scapi._find_server_folder(
-            12345,
+        res = self.scapi._find_server_folder(False)
+        mock_find_folder.assert_called_once_with(
+            'StorageCenter/ScServerFolder/GetList',
             self.configuration.dell_sc_server_folder)
+        self.assertEqual(self.SVR_FLDR, res, 'Unexpected server folder')
+
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_create_folder_path',
+                       return_value=SVR_FLDR)
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_find_folder',
+                       return_value=None)
+    def test_find_server_folder_create_folder(self,
+                                              mock_find_folder,
+                                              mock_create_folder_path,
+                                              mock_close_connection,
+                                              mock_open_connection,
+                                              mock_init):
+        # Test case where specified server folder is not found and must be
+        # created
+        res = self.scapi._find_server_folder(True)
         mock_find_folder.assert_called_once_with(
             'StorageCenter/ScServerFolder/GetList',
-            12345,
             self.configuration.dell_sc_server_folder)
+        self.assertTrue(mock_create_folder_path.called)
         self.assertEqual(self.SVR_FLDR, res, 'Unexpected server folder')
 
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_find_folder',
+                       return_value=None)
+    def test_find_server_folder_fail(self,
+                                     mock_find_folder,
+                                     mock_close_connection,
+                                     mock_open_connection,
+                                     mock_init):
+        # Test case where _find_server_folder returns none
+        res = self.scapi._find_server_folder(
+            False)
+        mock_find_folder.assert_called_once_with(
+            'StorageCenter/ScServerFolder/GetList',
+            self.configuration.dell_sc_volume_folder)
+        self.assertIsNone(res, 'Expected None')
+
     @mock.patch.object(dell_storagecenter_api.HttpClient,
                        'post',
                        return_value=RESPONSE_200)
@@ -1969,7 +2149,7 @@ class DellSCSanAPITestCase(test.TestCase):
                            mock_close_connection,
                            mock_open_connection,
                            mock_init):
-        res = self.scapi._find_serveros(12345, 'Red Hat Linux 6.x')
+        res = self.scapi._find_serveros('Red Hat Linux 6.x')
         self.assertTrue(mock_get_json.called)
         self.assertTrue(mock_post.called)
         self.assertEqual('64702.38', res, 'Wrong InstanceId')
@@ -1987,7 +2167,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                      mock_open_connection,
                                      mock_init):
         # Test requesting a Server OS that will not be found
-        res = self.scapi._find_serveros(12345, 'Non existent OS')
+        res = self.scapi._find_serveros('Non existent OS')
         self.assertTrue(mock_get_json.called)
         self.assertTrue(mock_post.called)
         self.assertIsNone(res, 'None expected')
@@ -2000,7 +2180,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                   mock_close_connection,
                                   mock_open_connection,
                                   mock_init):
-        res = self.scapi._find_serveros(12345, 'Red Hat Linux 6.x')
+        res = self.scapi._find_serveros('Red Hat Linux 6.x')
         self.assertEqual(None, res, 'None expected')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@@ -2016,8 +2196,6 @@ class DellSCSanAPITestCase(test.TestCase):
                                          mock_open_connection,
                                          mock_init):
         res = self.scapi.create_server_multiple_hbas(
-            12345,
-            self.configuration.dell_sc_server_folder,
             self.WWNS)
         self.assertTrue(mock_create_server.called)
         self.assertTrue(mock_add_hba.called)
@@ -2048,8 +2226,6 @@ class DellSCSanAPITestCase(test.TestCase):
                            mock_open_connection,
                            mock_init):
         res = self.scapi.create_server(
-            12345,
-            self.configuration.dell_sc_server_folder,
             self.IQN,
             False)
         self.assertTrue(mock_find_serveros.called)
@@ -2083,8 +2259,6 @@ class DellSCSanAPITestCase(test.TestCase):
                                         mock_open_connection,
                                         mock_init):
         res = self.scapi.create_server(
-            12345,
-            self.configuration.dell_sc_server_folder,
             self.IQN,
             False)
         self.assertTrue(mock_find_serveros.called)
@@ -2096,9 +2270,6 @@ class DellSCSanAPITestCase(test.TestCase):
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_first_result',
                        return_value=SCSERVER)
-    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_create_server_folder_path',
-                       return_value=None)
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_find_server_folder',
                        return_value=None)
@@ -2112,19 +2283,15 @@ class DellSCSanAPITestCase(test.TestCase):
                                           mock_post,
                                           mock_find_serveros,
                                           mock_find_server_folder,
-                                          mock_create_svr_fldr_path,
                                           mock_first_result,
                                           mock_add_hba,
                                           mock_close_connection,
                                           mock_open_connection,
                                           mock_init):
         res = self.scapi.create_server(
-            12345,
-            self.configuration.dell_sc_server_folder,
             self.IQN,
             False)
         self.assertTrue(mock_find_server_folder.called)
-        self.assertTrue(mock_create_svr_fldr_path.called)
         self.assertEqual(self.SCSERVER, res, 'Unexpected ScServer')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@@ -2133,9 +2300,6 @@ class DellSCSanAPITestCase(test.TestCase):
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_first_result',
                        return_value=SCSERVER)
-    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_create_server_folder_path',
-                       return_value=None)
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_find_server_folder',
                        return_value=None)
@@ -2149,15 +2313,12 @@ class DellSCSanAPITestCase(test.TestCase):
                                    mock_post,
                                    mock_find_serveros,
                                    mock_find_server_folder,
-                                   mock_create_svr_fldr_path,
                                    mock_first_result,
                                    mock_add_hba,
                                    mock_close_connection,
                                    mock_open_connection,
                                    mock_init):
         res = self.scapi.create_server(
-            12345,
-            self.configuration.dell_sc_server_folder,
             self.IQN,
             False)
         self.assertIsNone(res, 'None expected')
@@ -2168,9 +2329,6 @@ class DellSCSanAPITestCase(test.TestCase):
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_first_result',
                        return_value=None)
-    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_create_server_folder_path',
-                       return_value=None)
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_find_server_folder',
                        return_value=None)
@@ -2184,7 +2342,6 @@ class DellSCSanAPITestCase(test.TestCase):
                                      mock_post,
                                      mock_find_serveros,
                                      mock_find_server_folder,
-                                     mock_create_svr_fldr_path,
                                      mock_first_result,
                                      mock_add_hba,
                                      mock_close_connection,
@@ -2192,8 +2349,6 @@ class DellSCSanAPITestCase(test.TestCase):
                                      mock_init):
         # Test create server where _first_result is None
         res = self.scapi.create_server(
-            12345,
-            self.configuration.dell_sc_server_folder,
             self.IQN,
             False)
         self.assertIsNone(res, 'None expected')
@@ -2228,8 +2383,6 @@ class DellSCSanAPITestCase(test.TestCase):
                                        mock_init):
         # Tests create server where add hba fails
         res = self.scapi.create_server(
-            12345,
-            self.configuration.dell_sc_server_folder,
             self.IQN,
             False)
         self.assertTrue(mock_delete_server.called)
@@ -2251,8 +2404,7 @@ class DellSCSanAPITestCase(test.TestCase):
                          mock_close_connection,
                          mock_open_connection,
                          mock_init):
-        res = self.scapi.find_server(12345,
-                                     self.IQN)
+        res = self.scapi.find_server(self.IQN)
         self.assertTrue(mock_find_serverhba.called)
         self.assertTrue(mock_first_result.called)
         self.assertIsNotNone(res, 'Expected ScServer')
@@ -2271,8 +2423,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                 mock_init):
         # Test case where a ScServer HBA does not exist with the specified IQN
         # or WWN
-        res = self.scapi.find_server(12345,
-                                     self.IQN)
+        res = self.scapi.find_server(self.IQN)
         self.assertTrue(mock_find_serverhba.called)
         self.assertIsNone(res, 'Expected None')
 
@@ -2290,8 +2441,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                  mock_init):
         # Test case where a ScServer does not exist with the specified
         # ScServerHba
-        res = self.scapi.find_server(12345,
-                                     self.IQN)
+        res = self.scapi.find_server(self.IQN)
         self.assertTrue(mock_find_serverhba.called)
         self.assertIsNone(res, 'Expected None')
 
@@ -2307,8 +2457,7 @@ class DellSCSanAPITestCase(test.TestCase):
                             mock_close_connection,
                             mock_open_connection,
                             mock_init):
-        res = self.scapi.find_server(12345,
-                                     self.IQN)
+        res = self.scapi.find_server(self.IQN)
         self.assertTrue(mock_post.called)
         self.assertTrue(mock_first_result.called)
         self.assertIsNotNone(res, 'Expected ScServerHba')
@@ -2323,8 +2472,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                     mock_init):
         # Test case where a ScServer does not exist with the specified
         # ScServerHba
-        res = self.scapi.find_server(12345,
-                                     self.IQN)
+        res = self.scapi.find_server(self.IQN)
         self.assertIsNone(res, 'Expected None')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@@ -3054,6 +3202,48 @@ class DellSCSanAPITestCase(test.TestCase):
         self.assertTrue(mock_first_result.called)
         self.assertEqual(self.MAP_PROFILE, res, 'Incorrect ScMappingProfile')
 
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_get_id')
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_first_result')
+    @mock.patch.object(dell_storagecenter_api.HttpClient,
+                       'post')
+    def test_map_volume_no_vol_id(self,
+                                  mock_post,
+                                  mock_first_result,
+                                  mock_get_id,
+                                  mock_close_connection,
+                                  mock_open_connection,
+                                  mock_init):
+        # Test case where ScVolume instanceId is None
+        mock_get_id.side_effect = [None, '64702.47']
+        res = self.scapi.map_volume(self.VOLUME,
+                                    self.SCSERVER)
+        self.assertFalse(mock_post.called)
+        self.assertFalse(mock_first_result.called)
+        self.assertIsNone(res, 'None expected')
+
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_get_id')
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_first_result')
+    @mock.patch.object(dell_storagecenter_api.HttpClient,
+                       'post')
+    def test_map_volume_no_server_id(self,
+                                     mock_post,
+                                     mock_first_result,
+                                     mock_get_id,
+                                     mock_close_connection,
+                                     mock_open_connection,
+                                     mock_init):
+        # Test case where ScVolume instanceId is None
+        mock_get_id.side_effect = ['64702.3494', None]
+        res = self.scapi.map_volume(self.VOLUME,
+                                    self.SCSERVER)
+        self.assertFalse(mock_post.called)
+        self.assertFalse(mock_first_result.called)
+        self.assertIsNone(res, 'None expected')
+
     @mock.patch.object(dell_storagecenter_api.HttpClient,
                        'post',
                        return_value=RESPONSE_204)
@@ -3145,6 +3335,62 @@ class DellSCSanAPITestCase(test.TestCase):
         self.assertTrue(mock_delete.called)
         self.assertFalse(res, False)
 
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_get_id')
+    @mock.patch.object(dell_storagecenter_api.HttpClient,
+                       'delete',
+                       return_value=RESPONSE_200)
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_get_json',
+                       return_value=MAP_PROFILES)
+    @mock.patch.object(dell_storagecenter_api.HttpClient,
+                       'get',
+                       return_value=RESPONSE_200)
+    def test_unmap_volume_no_vol_id(self,
+                                    mock_get,
+                                    mock_get_json,
+                                    mock_delete,
+                                    mock_get_id,
+                                    mock_close_connection,
+                                    mock_open_connection,
+                                    mock_init):
+        # Test case where ScVolume instanceId = None
+        mock_get_id.side_effect = [None, '64702.47']
+        res = self.scapi.unmap_volume(self.VOLUME,
+                                      self.SCSERVER)
+        self.assertFalse(mock_get.called)
+        self.assertFalse(mock_get_json.called)
+        self.assertFalse(mock_delete.called)
+        self.assertTrue(res)
+
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_get_id')
+    @mock.patch.object(dell_storagecenter_api.HttpClient,
+                       'delete',
+                       return_value=RESPONSE_200)
+    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
+                       '_get_json',
+                       return_value=MAP_PROFILES)
+    @mock.patch.object(dell_storagecenter_api.HttpClient,
+                       'get',
+                       return_value=RESPONSE_200)
+    def test_unmap_volume_no_server_id(self,
+                                       mock_get,
+                                       mock_get_json,
+                                       mock_delete,
+                                       mock_get_id,
+                                       mock_close_connection,
+                                       mock_open_connection,
+                                       mock_init):
+        # Test case where ScVolume instanceId = None
+        mock_get_id.side_effect = ['64702.3494', None]
+        res = self.scapi.unmap_volume(self.VOLUME,
+                                      self.SCSERVER)
+        self.assertFalse(mock_get.called)
+        self.assertFalse(mock_get_json.called)
+        self.assertFalse(mock_delete.called)
+        self.assertTrue(res)
+
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_get_json',
                        return_value=STRG_USAGE)
@@ -3157,17 +3403,24 @@ class DellSCSanAPITestCase(test.TestCase):
                                mock_close_connection,
                                mock_open_connection,
                                mock_init):
-        res = self.scapi.get_storage_usage(64702)
+        res = self.scapi.get_storage_usage()
         self.assertTrue(mock_get.called)
         self.assertTrue(mock_get_json.called)
         self.assertEqual(self.STRG_USAGE, res, 'Unexpected ScStorageUsage')
 
+    @mock.patch.object(dell_storagecenter_api.HttpClient,
+                       'get',
+                       return_value=RESPONSE_204)
     def test_get_storage_usage_no_ssn(self,
+                                      mock_get,
                                       mock_close_connection,
                                       mock_open_connection,
                                       mock_init):
         # Test case where SSN is none
-        res = self.scapi.get_storage_usage(None)
+        self.scapi.ssn = None
+        res = self.scapi.get_storage_usage()
+        self.scapi.ssn = 12345
+        self.assertFalse(mock_get.called)
         self.assertIsNone(res, 'None expected')
 
     @mock.patch.object(dell_storagecenter_api.HttpClient,
@@ -3179,7 +3432,7 @@ class DellSCSanAPITestCase(test.TestCase):
                                        mock_close_connection,
                                        mock_open_connection,
                                        mock_init):
-        res = self.scapi.get_storage_usage(64702)
+        res = self.scapi.get_storage_usage()
         self.assertTrue(mock_get.called)
         self.assertIsNone(res, 'None expected')
 
@@ -3408,21 +3661,15 @@ class DellSCSanAPITestCase(test.TestCase):
         vol_name = u'Test_create_vol'
         res = self.scapi.create_view_volume(
             vol_name,
-            self.configuration.dell_sc_volume_folder,
             self.TST_RPLAY)
         self.assertTrue(mock_post.called)
-        mock_find_volume_folder.assert_called_once_with(
-            64702,
-            self.configuration.dell_sc_volume_folder)
+        mock_find_volume_folder.assert_called_once_with(True)
         self.assertTrue(mock_first_result.called)
         self.assertEqual(self.VOLUME, res, 'Unexpected ScVolume')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_first_result',
                        return_value=VOLUME)
-    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_create_volume_folder_path',
-                       return_value=FLDR)
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_find_volume_folder',
                        return_value=None)
@@ -3432,7 +3679,6 @@ class DellSCSanAPITestCase(test.TestCase):
     def test_create_view_volume_create_fldr(self,
                                             mock_post,
                                             mock_find_volume_folder,
-                                            mock_create_volume_folder,
                                             mock_first_result,
                                             mock_close_connection,
                                             mock_open_connection,
@@ -3441,24 +3687,15 @@ class DellSCSanAPITestCase(test.TestCase):
         vol_name = u'Test_create_vol'
         res = self.scapi.create_view_volume(
             vol_name,
-            self.configuration.dell_sc_volume_folder,
             self.TST_RPLAY)
         self.assertTrue(mock_post.called)
-        mock_find_volume_folder.assert_called_once_with(
-            64702,
-            self.configuration.dell_sc_volume_folder)
-        mock_create_volume_folder.assert_called_once_with(
-            64702,
-            self.configuration.dell_sc_volume_folder)
+        mock_find_volume_folder.assert_called_once_with(True)
         self.assertTrue(mock_first_result.called)
         self.assertEqual(self.VOLUME, res, 'Unexpected ScVolume')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_first_result',
                        return_value=VOLUME)
-    @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
-                       '_create_volume_folder_path',
-                       return_value=None)
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
                        '_find_volume_folder',
                        return_value=None)
@@ -3468,7 +3705,6 @@ class DellSCSanAPITestCase(test.TestCase):
     def test_create_view_volume_no_vol_fldr(self,
                                             mock_post,
                                             mock_find_volume_folder,
-                                            mock_create_volume_folder,
                                             mock_first_result,
                                             mock_close_connection,
                                             mock_open_connection,
@@ -3477,15 +3713,9 @@ class DellSCSanAPITestCase(test.TestCase):
         vol_name = u'Test_create_vol'
         res = self.scapi.create_view_volume(
             vol_name,
-            self.configuration.dell_sc_volume_folder,
             self.TST_RPLAY)
         self.assertTrue(mock_post.called)
-        mock_find_volume_folder.assert_called_once_with(
-            64702,
-            self.configuration.dell_sc_volume_folder)
-        mock_create_volume_folder.assert_called_once_with(
-            64702,
-            self.configuration.dell_sc_volume_folder)
+        mock_find_volume_folder.assert_called_once_with(True)
         self.assertTrue(mock_first_result.called)
         self.assertEqual(self.VOLUME, res, 'Unexpected ScVolume')
 
@@ -3505,12 +3735,9 @@ class DellSCSanAPITestCase(test.TestCase):
         vol_name = u'Test_create_vol'
         res = self.scapi.create_view_volume(
             vol_name,
-            self.configuration.dell_sc_volume_folder,
             self.TST_RPLAY)
         self.assertTrue(mock_post.called)
-        mock_find_volume_folder.assert_called_once_with(
-            64702,
-            self.configuration.dell_sc_volume_folder)
+        mock_find_volume_folder.assert_called_once_with(True)
         self.assertIsNone(res, 'Expected None')
 
     @mock.patch.object(dell_storagecenter_api.StorageCenterApi,
@@ -3528,14 +3755,12 @@ class DellSCSanAPITestCase(test.TestCase):
         vol_name = u'Test_create_clone_vol'
         res = self.scapi.create_cloned_volume(
             vol_name,
-            self.configuration.dell_sc_volume_folder,
             self.VOLUME)
         mock_create_replay.assert_called_once_with(self.VOLUME,
                                                    'Cinder Clone Replay',
                                                    60)
         mock_create_view_volume.assert_called_once_with(
             vol_name,
-            self.configuration.dell_sc_volume_folder,
             self.RPLAY)
         self.assertEqual(self.VOLUME, res, 'Unexpected ScVolume')
 
@@ -3552,7 +3777,6 @@ class DellSCSanAPITestCase(test.TestCase):
         vol_name = u'Test_create_clone_vol'
         res = self.scapi.create_cloned_volume(
             vol_name,
-            self.configuration.dell_sc_volume_folder,
             self.VOLUME)
         mock_create_replay.assert_called_once_with(self.VOLUME,
                                                    'Cinder Clone Replay',
@@ -3670,8 +3894,8 @@ class DellSCSanAPIConnectionTestCase(test.TestCase):
         self.configuration.san_login = "admin"
         self.configuration.san_password = "mmm"
         self.configuration.dell_sc_ssn = 12345
-        self.configuration.dell_sc_server_folder = 'opnstktst'
-        self.configuration.dell_sc_volume_folder = 'opnstktst'
+        self.configuration.dell_sc_server_folder = 'openstack'
+        self.configuration.dell_sc_volume_folder = 'openstack'
         self.configuration.dell_sc_api_port = 3033
         self.configuration.iscsi_ip_address = '192.168.1.1'
         self.configuration.iscsi_port = 3260
@@ -3684,6 +3908,11 @@ class DellSCSanAPIConnectionTestCase(test.TestCase):
             self.configuration.san_login,
             self.configuration.san_password)
 
+        # Set up the scapi configuration vars
+        self.scapi.ssn = self.configuration.dell_sc_ssn
+        self.scapi.sfname = self.configuration.dell_sc_server_folder
+        self.scapi.vfname = self.configuration.dell_sc_volume_folder
+
     @mock.patch.object(dell_storagecenter_api.HttpClient,
                        'post',
                        return_value=RESPONSE_200)
index fb875cd1a75c1c335b7f673848e6617ce9a45c7a..8579e9aae769c457c26ee432024d4b4d25d2c44b 100644 (file)
@@ -122,12 +122,27 @@ class StorageCenterApiHelper(object):
         self.config = config
 
     def open_connection(self):
-        '''Open connection to Enterprise Manager.'''
-        connection = StorageCenterApi(self.config.san_ip,
-                                      self.config.dell_sc_api_port,
-                                      self.config.san_login,
-                                      self.config.san_password)
-        connection.open_connection()
+        connection = None
+        ssn = self.config.dell_sc_ssn
+        LOG.info(_LI('open_connection to %(s)s at %(ip)s'),
+                 {'s': ssn,
+                  'ip': self.config.san_ip})
+        if ssn:
+            '''Open connection to Enterprise Manager.'''
+            connection = StorageCenterApi(self.config.san_ip,
+                                          self.config.dell_sc_api_port,
+                                          self.config.san_login,
+                                          self.config.san_password)
+            # This instance is for a single backend.  That backend has a
+            # few items of information we should save rather than passing them
+            # about.
+            connection.ssn = ssn
+            connection.vfname = self.config.dell_sc_volume_folder
+            connection.sfname = self.config.dell_sc_server_folder
+            connection.open_connection()
+        else:
+            raise exception.VolumeBackendAPIException('Configuration error.  '
+                                                      'dell_sc_ssn not set.')
         return connection
 
 
@@ -142,6 +157,9 @@ class StorageCenterApi(object):
 
     def __init__(self, host, port, user, password):
         self.notes = 'Created by Dell Cinder Driver'
+        self.ssn = None
+        self.vfname = 'openstack'
+        self.sfname = 'openstack'
         self.client = HttpClient(host,
                                  port,
                                  user,
@@ -228,32 +246,32 @@ class StorageCenterApi(object):
                          'r': r.reason})
         self.client = None
 
-    def find_sc(self, ssn):
-        '''This is really just a check that the sc is there and being managed by
-        EM.
+    def find_sc(self):
+        '''This is really just a check that the sc is there and being managed
+        by EM.
         '''
         r = self.client.get('StorageCenter/StorageCenter')
         result = self._get_result(r,
                                   'scSerialNumber',
-                                  ssn)
+                                  self.ssn)
         if result is None:
             LOG.error(_LE('Failed to find %(s)s.  Result %(r)s'),
-                      {'s': ssn,
+                      {'s': self.ssn,
                        'r': r})
             raise exception.VolumeBackendAPIException(
                 _('Failed to find Storage Center'))
 
         return self._get_id(result)
 
-    # Volume functions
+    # Folder functions
 
-    def _create_folder(self, url, ssn, parent, folder):
+    def _create_folder(self, url, parent, folder):
         '''This is generic to server and volume folders.
         '''
         f = None
         payload = {}
         payload['Name'] = folder
-        payload['StorageCenter'] = ssn
+        payload['StorageCenter'] = self.ssn
         if parent != '':
             payload['Parent'] = parent
         payload['Notes'] = self.notes
@@ -269,7 +287,7 @@ class StorageCenterApi(object):
             f = self._first_result(r)
         return f
 
-    def _create_folder_path(self, url, ssn, foldername):
+    def _create_folder_path(self, url, foldername):
         '''This is generic to server and volume folders.
         '''
         path = self._path_to_array(foldername)
@@ -284,14 +302,12 @@ class StorageCenterApi(object):
             if found:
                 listurl = url + '/GetList'
                 f = self._find_folder(listurl,
-                                      ssn,
                                       folderpath)
                 if f is None:
                     found = False
             # We didn't find it so create it
             if found is False:
                 f = self._create_folder(url,
-                                        ssn,
                                         instanceId,
                                         folder)
             # If we haven't found a folder or created it then leave
@@ -304,7 +320,7 @@ class StorageCenterApi(object):
             folderpath = folderpath + '/'
         return f
 
-    def _find_folder(self, url, ssn, foldername):
+    def _find_folder(self, url, foldername):
         '''Most of the time the folder will already have been created so
         we look for the end folder and check that the rest of the path is
         right.
@@ -312,13 +328,13 @@ class StorageCenterApi(object):
         This is generic to server and volume folders.
         '''
         pf = PayloadFilter()
-        pf.append('scSerialNumber', ssn)
+        pf.append('scSerialNumber', self.ssn)
         basename = os.path.basename(foldername)
         pf.append('Name', basename)
-        # If we have any kind of path we add '/' to match the storage
-        # center's convention and throw it into the filters.
+        # If we have any kind of path we throw it into the filters.
         folderpath = os.path.dirname(foldername)
         if folderpath != '':
+            # SC convention is to end with a '/' so make sure we do.
             folderpath += '/'
             pf.append('folderPath', folderpath)
         folder = None
@@ -335,15 +351,14 @@ class StorageCenterApi(object):
                        'r': r.reason})
         return folder
 
-    def _create_volume_folder_path(self, ssn, foldername):
-        return self._create_folder_path('StorageCenter/ScVolumeFolder',
-                                        ssn,
-                                        foldername)
-
-    def _find_volume_folder(self, ssn, foldername):
-        return self._find_folder('StorageCenter/ScVolumeFolder/GetList',
-                                 ssn,
-                                 foldername)
+    def _find_volume_folder(self, create=False):
+        folder = self._find_folder('StorageCenter/ScVolumeFolder/GetList',
+                                   self.vfname)
+        # Doesn't exist?  make it
+        if folder is None and create is True:
+            folder = self._create_folder_path('StorageCenter/ScVolumeFolder',
+                                              self.vfname)
+        return folder
 
     def _init_volume(self, scvolume):
         '''Maps the volume to a random server and immediately unmaps
@@ -370,37 +385,34 @@ class StorageCenterApi(object):
                                       scserver)
                     break
 
-    def create_volume(self, name, size, ssn, volfolder):
+    def create_volume(self, name, size):
         '''This creates a new volume on the storage center.  It
-        will create it in volfolder.  If volfolder does not
-        exist it will create it.  If it cannot create volfolder
+        will create it in a folder called self.vfname.  If self.vfname
+        does not exist it will create it.  If it cannot create it
         the volume will be created in the root.
         '''
-        scvolume = None
-        # Find our folder
         LOG.debug('Create Volume %(name)s %(ssn)s %(folder)s',
                   {'name': name,
-                   'ssn': ssn,
-                   'folder': volfolder})
-        folder = self._find_volume_folder(ssn,
-                                          volfolder)
+                   'ssn': self.ssn,
+                   'folder': self.vfname})
 
-        # Doesn't exist?  make it
-        if folder is None:
-            folder = self._create_volume_folder_path(ssn,
-                                                     volfolder)
+        # Find our folder
+        folder = self._find_volume_folder(True)
 
         # If we actually have a place to put our volume create it
         if folder is None:
-            LOG.error(_LE('Unable to create folder %s'),
-                      volfolder)
+            LOG.warning(_LW('Unable to create folder %s'),
+                        self.vfname)
+
+        # Init our return.
+        scvolume = None
 
         # Create the volume
         payload = {}
         payload['Name'] = name
         payload['Notes'] = self.notes
         payload['Size'] = '%d GB' % size
-        payload['StorageCenter'] = ssn
+        payload['StorageCenter'] = self.ssn
         if folder is not None:
             payload['VolumeFolder'] = self._get_id(folder)
         r = self.client.post('StorageCenter/ScVolume',
@@ -412,6 +424,7 @@ class StorageCenterApi(object):
                       {'name': name,
                        'c': r.status_code,
                        'r': r.reason})
+            return None
         if scvolume:
             LOG.info(_LI('Created volume %(instanceId)s: %(name)s'),
                      {'instanceId': scvolume['instanceId'],
@@ -421,46 +434,84 @@ class StorageCenterApi(object):
                           '  Attempting to locate volume'))
             # In theory it is there since success was returned.
             # Try one last time to find it before returning.
-            scvolume = self.find_volume(ssn, name, None)
+            scvolume = self.find_volume(name)
 
         return scvolume
 
-    def find_volume(self, ssn, name=None, instanceid=None):
-        '''search ssn for volume of name and/or instance id
+    def _get_volume_list(self, name, filterbyvfname=True):
+        '''Return the list of volumes with name of name.
+        :param name: Volume name.
+        :param filterbyvfname:  If true filters by the preset folder name.
+        :return: Returns the scvolume or None.
         '''
-        LOG.debug('finding volume %(sn)s : %(name)s : %(id)s',
-                  {'sn': ssn,
-                   'name': name,
-                   'id': instanceid})
+        result = None
         pf = PayloadFilter()
-        pf.append('scSerialNumber', ssn)
-        # We need at least a name and or an instance id.  If we have
-        # that we can find a volume.
-        if instanceid is not None:
-            pf.append('instanceId', instanceid)
-        elif name is not None:
+        pf.append('scSerialNumber', self.ssn)
+        # We need a name to find a volume.
+        if name is not None:
             pf.append('Name', name)
         else:
             return None
+        # set folderPath
+        if filterbyvfname:
+            vfname = (self.vfname if self.vfname.endswith('/')
+                      else self.vfname + '/')
+            pf.append('volumeFolderPath', vfname)
         r = self.client.post('StorageCenter/ScVolume/GetList',
                              pf.payload)
         if r.status_code != 200:
-            LOG.debug('ScVolume GetList error %(i)s: %(c)d %(r)s',
-                      {'i': instanceid,
+            LOG.debug('ScVolume GetList error %(n)s: %(c)d %(r)s',
+                      {'n': name,
                        'c': r.status_code,
                        'r': r.reason})
-        return self._first_result(r)
+        else:
+            result = self._get_json(r)
+        # We return None if there was an error and a list if the command
+        # succeeded. It might be an empty list.
+        return result
 
-    def delete_volume(self, ssn, name):
-        # find our volume
-        vol = self.find_volume(ssn, name, None)
+    def find_volume(self, name):
+        '''Search self.ssn for volume of name.
+        '''
+        LOG.debug('Searching %(sn)s for %(name)s',
+                  {'sn': self.ssn,
+                   'name': name})
+
+        # Cannot find a volume without the name
+        if name is None:
+            return None
+
+        # Look for our volume in our folder.
+        vollist = self._get_volume_list(name,
+                                        True)
+        # If an empty list was returned they probably moved the volumes or
+        # changed the folder name so try again without the folder.
+        if not vollist:
+            LOG.debug('Cannot find volume %(n)s in %(v)s.  Searching SC.',
+                      {'n': name,
+                       'v': self.vfname})
+            vollist = self._get_volume_list(name,
+                                            False)
+
+        # If multiple volumes of the same name are found we need to error.
+        if len(vollist) > 1:
+            # blow up
+            raise exception.VolumeBackendAPIException(
+                _('Multiple copies of volume %s found.') % name)
+
+        # We made it and should have a valid volume.
+        return None if not vollist else vollist[0]
+
+    def delete_volume(self, name):
+        # Delete our volume.
+        vol = self.find_volume(name)
         if vol is not None:
             r = self.client.delete('StorageCenter/ScVolume/%s'
                                    % self._get_id(vol))
             if r.status_code != 200:
                 raise exception.VolumeBackendAPIException(
                     _('Error deleting volume %(ssn)s: %(sn)s: %(c)d %(r)s') %
-                    {'ssn': ssn,
+                    {'ssn': self.ssn,
                      'sn': name,
                      'c': r.status_code,
                      'r': r.reason})
@@ -471,15 +522,13 @@ class StorageCenterApi(object):
         # If we can't find the volume then it is effectively gone.
         return True
 
-    def _create_server_folder_path(self, ssn, foldername):
-        return self._create_folder_path('StorageCenter/ScServerFolder',
-                                        ssn,
-                                        foldername)
-
-    def _find_server_folder(self, ssn, foldername):
-        return self._find_folder('StorageCenter/ScServerFolder/GetList',
-                                 ssn,
-                                 foldername)
+    def _find_server_folder(self, create=False):
+        folder = self._find_folder('StorageCenter/ScServerFolder/GetList',
+                                   self.sfname)
+        if folder is None and create is True:
+            folder = self._create_folder_path('StorageCenter/ScServerFolder',
+                                              self.sfname)
+        return folder
 
     def _add_hba(self, scserver, wwnoriscsiname, isfc=False):
         '''Adds an HBA to the scserver.  The HBA will be added
@@ -506,12 +555,12 @@ class StorageCenterApi(object):
 
     # We do not know that we are red hat linux 6.x but that works
     # best for red hat and ubuntu.  So, there.
-    def _find_serveros(self, ssn, osname='Red Hat Linux 6.x'):
+    def _find_serveros(self, osname='Red Hat Linux 6.x'):
         '''Returns the serveros instance id of the specified osname.
         Required to create a server.
         '''
         pf = PayloadFilter()
-        pf.append('scSerialNumber', ssn)
+        pf.append('scSerialNumber', self.ssn)
         r = self.client.post('StorageCenter/ScServerOperatingSystem/GetList',
                              pf.payload)
         if r.status_code == 200:
@@ -527,7 +576,7 @@ class StorageCenterApi(object):
                      'r': r.reason})
         return None
 
-    def create_server_multiple_hbas(self, ssn, foldername, wwns):
+    def create_server_multiple_hbas(self, wwns):
         '''Same as create_server except it can take a list of hbas.  hbas
         can be wwns or iqns.
         '''
@@ -537,9 +586,7 @@ class StorageCenterApi(object):
         for wwn in wwns:
             if scserver is None:
                 # Use the fist wwn to create the server.
-                scserver = self.create_server(ssn,
-                                              foldername,
-                                              wwn,
+                scserver = self.create_server(wwn,
                                               True)
             else:
                 # Add the wwn to our server
@@ -548,27 +595,23 @@ class StorageCenterApi(object):
                               True)
         return scserver
 
-    def create_server(self, ssn, foldername, wwnoriscsiname, isfc=False):
-        '''creates a server on the the storage center ssn.  Adds the first
+    def create_server(self, wwnoriscsiname, isfc=False):
+        '''creates a server on the the storage center self.ssn.  Adds the first
         HBA to it.
         '''
         scserver = None
         payload = {}
         payload['Name'] = 'Server_' + wwnoriscsiname
-        payload['StorageCenter'] = ssn
+        payload['StorageCenter'] = self.ssn
         payload['Notes'] = self.notes
         # We pick Red Hat Linux 6.x because it supports multipath and
         # will attach luns to paths as they are found.
-        scserveros = self._find_serveros(ssn, 'Red Hat Linux 6.x')
+        scserveros = self._find_serveros('Red Hat Linux 6.x')
         if scserveros is not None:
             payload['OperatingSystem'] = scserveros
 
         # Find our folder or make it
-        folder = self._find_server_folder(ssn,
-                                          foldername)
-        if folder is None:
-            folder = self._create_server_folder_path(ssn,
-                                                     foldername)
+        folder = self._find_server_folder(True)
 
         # At this point it doesn't matter if the folder was created or not.
         # We just attempt to create the server.  Let it be in the root if
@@ -600,7 +643,7 @@ class StorageCenterApi(object):
         # Success or failure is determined by the caller
         return scserver
 
-    def find_server(self, ssn, instance_name):
+    def find_server(self, instance_name):
         '''Hunts for a server by looking for an HBA with the server's IQN
         or wwn.
 
@@ -608,13 +651,13 @@ class StorageCenterApi(object):
         '''
         scserver = None
         # We search for our server by first finding our HBA
-        hba = self._find_serverhba(ssn, instance_name)
+        hba = self._find_serverhba(instance_name)
         # Once created hbas stay in the system.  So it isn't enough
         # that we found one it actually has to be attached to a
         # server.
         if hba is not None and hba.get('server') is not None:
             pf = PayloadFilter()
-            pf.append('scSerialNumber', ssn)
+            pf.append('scSerialNumber', self.ssn)
             pf.append('instanceId', self._get_id(hba['server']))
             r = self.client.post('StorageCenter/ScServer/GetList',
                                  pf.payload)
@@ -629,7 +672,7 @@ class StorageCenterApi(object):
                       instance_name)
         return scserver
 
-    def _find_serverhba(self, ssn, instance_name):
+    def _find_serverhba(self, instance_name):
         '''Hunts for a sc server HBA by looking for an HBA with the
         server's IQN or wwn.
 
@@ -638,7 +681,7 @@ class StorageCenterApi(object):
         scserverhba = None
         # We search for our server by first finding our HBA
         pf = PayloadFilter()
-        pf.append('scSerialNumber', ssn)
+        pf.append('scSerialNumber', self.ssn)
         pf.append('instanceName', instance_name)
         r = self.client.post('StorageCenter/ScServerHba/GetList',
                              pf.payload)
@@ -984,12 +1027,12 @@ class StorageCenterApi(object):
                 rtn = False
         return rtn
 
-    def get_storage_usage(self, ssn):
+    def get_storage_usage(self):
         '''get_storage_usage'''
         storageusage = None
-        if ssn is not None:
+        if self.ssn is not None:
             r = self.client.get('StorageCenter/StorageCenter/%s/StorageUsage'
-                                % ssn)
+                                % self.ssn)
             if r.status_code == 200:
                 storageusage = self._get_json(r)
             else:
@@ -1085,21 +1128,12 @@ class StorageCenterApi(object):
         # We either couldn't find it or expired it.
         return True
 
-    def create_view_volume(self, volname, volfolder, screplay):
+    def create_view_volume(self, volname, screplay):
         '''create_view_volume
 
-        creates a new volume named volname in the folder
-        volfolder from the screplay.
+        creates a new volume named volname from the screplay.
         '''
-        # find our ssn and get our folder
-        ssn = screplay.get('scSerialNumber')
-        folder = self._find_volume_folder(ssn,
-                                          volfolder)
-
-        # Doesn't exist?  make it
-        if folder is None:
-            folder = self._create_volume_folder_path(ssn,
-                                                     volfolder)
+        folder = self._find_volume_folder(True)
 
         # payload is just the volume name and folder if we have one.
         payload = {}
@@ -1124,7 +1158,7 @@ class StorageCenterApi(object):
 
         return volume
 
-    def create_cloned_volume(self, volumename, volumefolder, scvolume):
+    def create_cloned_volume(self, volumename, scvolume):
         '''create_cloned_volume
 
         creates a temporary replay and then creates a
@@ -1136,7 +1170,6 @@ class StorageCenterApi(object):
                                     60)
         if replay is not None:
             clone = self.create_view_volume(volumename,
-                                            volumefolder,
                                             replay)
         else:
             LOG.error(_LE('Error: unable to snap replay'))
index 207f1840d16a34411a3b0795fb66f5f265db7245..d44eeab0ad681f48213f474ccf620d2021f55e48 100644 (file)
@@ -81,30 +81,23 @@ class DellCommonDriver(san.SanDriver):
     def check_for_setup_error(self):
         '''Validates the configuration information.'''
         with self._client.open_connection() as api:
-            ssn = self.configuration.safe_get('dell_sc_ssn')
-            api.find_sc(ssn)
+            api.find_sc()
 
     def create_volume(self, volume):
         '''Create a volume.'''
+
+        # We use id as our name as it is unique.
         volume_name = volume.get('id')
         volume_size = volume.get('size')
-        LOG.debug('Creating volume %(name)s of size %(size)s',
-                  {'name': volume_name, 'size': volume_size})
+        LOG.debug('Creating volume %(n)s of size %(s)s',
+                  {'n': volume_name,
+                   's': volume_size})
         scvolume = None
         with self._client.open_connection() as api:
             try:
-                # we use id as our name as it s unique
-                volume_folder = self.configuration.dell_sc_volume_folder
-                ssn = api.find_sc(self.configuration.dell_sc_ssn)
-                LOG.debug('create_volume: %(name)s on %(ssn)s in %(vf)s',
-                          {'name': volume_name,
-                           'ssn': ssn,
-                           'vf': volume_folder})
-                if ssn is not None:
+                if api.find_sc():
                     scvolume = api.create_volume(volume_name,
-                                                 volume_size,
-                                                 ssn,
-                                                 volume_folder)
+                                                 volume_size)
             except Exception:
                 with excutils.save_and_reraise_exception():
                     LOG.error(_LE('Failed to create volume %s'),
@@ -120,10 +113,8 @@ class DellCommonDriver(san.SanDriver):
         LOG.debug('Deleting volume %s', volume_name)
         with self._client.open_connection() as api:
             try:
-                ssn = api.find_sc(self.configuration.dell_sc_ssn)
-                if ssn is not None:
-                    deleted = api.delete_volume(ssn,
-                                                volume_name)
+                if api.find_sc():
+                    deleted = api.delete_volume(volume_name)
             except Exception:
                 with excutils.save_and_reraise_exception():
                     LOG.error(_LE('Failed to delete volume %s'),
@@ -141,12 +132,11 @@ class DellCommonDriver(san.SanDriver):
         volume_name = snapshot.get('volume_id')
         snapshot_id = snapshot.get('id')
         LOG.debug('Creating snapshot %(snap)s on volume %(vol)s',
-                  {'snap': snapshot_id, 'vol': volume_name})
+                  {'snap': snapshot_id,
+                   'vol': volume_name})
         with self._client.open_connection() as api:
-            ssn = api.find_sc(self.configuration.dell_sc_ssn)
-            if ssn is not None:
-                scvolume = api.find_volume(ssn,
-                                           volume_name)
+            if api.find_sc():
+                scvolume = api.find_volume(volume_name)
                 if scvolume is not None:
                     if api.create_replay(scvolume,
                                          snapshot_id,
@@ -176,18 +166,15 @@ class DellCommonDriver(san.SanDriver):
              'src': src_volume_name})
         with self._client.open_connection() as api:
             try:
-                volume_folder = self.configuration.dell_sc_volume_folder
-                ssn = api.find_sc(self.configuration.dell_sc_ssn)
-                srcvol = api.find_volume(ssn,
-                                         src_volume_name)
-                if srcvol is not None:
-                    replay = api.find_replay(srcvol,
-                                             snapshot_id)
-                    if replay is not None:
-                        volume_name = volume.get('id')
-                        scvolume = api.create_view_volume(volume_name,
-                                                          volume_folder,
-                                                          replay)
+                if api.find_sc():
+                    srcvol = api.find_volume(src_volume_name)
+                    if srcvol is not None:
+                        replay = api.find_replay(srcvol,
+                                                 snapshot_id)
+                        if replay is not None:
+                            volume_name = volume.get('id')
+                            scvolume = api.create_view_volume(volume_name,
+                                                              replay)
             except Exception:
                 with excutils.save_and_reraise_exception():
                     LOG.error(_LE('Failed to create volume %s'),
@@ -210,14 +197,11 @@ class DellCommonDriver(san.SanDriver):
                    'vol': src_volume_name})
         with self._client.open_connection() as api:
             try:
-                volume_folder = self.configuration.dell_sc_volume_folder
-                ssn = api.find_sc(self.configuration.dell_sc_ssn)
-                srcvol = api.find_volume(ssn,
-                                         src_volume_name)
-                if srcvol is not None:
-                    scvolume = api.create_cloned_volume(volume_name,
-                                                        volume_folder,
-                                                        srcvol)
+                if api.find_sc():
+                    srcvol = api.find_volume(src_volume_name)
+                    if srcvol is not None:
+                        scvolume = api.create_cloned_volume(volume_name,
+                                                            srcvol)
             except Exception:
                 with excutils.save_and_reraise_exception():
                     LOG.error(_LE('Failed to create volume %s'),
@@ -238,10 +222,8 @@ class DellCommonDriver(san.SanDriver):
                   {'snap': snapshot_id,
                    'vol': volume_name})
         with self._client.open_connection() as api:
-            ssn = api.find_sc(self.configuration.dell_sc_ssn)
-            if ssn is not None:
-                scvolume = api.find_volume(ssn,
-                                           volume_name)
+            if api.find_sc():
+                scvolume = api.find_volume(volume_name)
                 if scvolume is not None:
                     if api.delete_replay(scvolume,
                                          snapshot_id):
@@ -270,10 +252,8 @@ class DellCommonDriver(san.SanDriver):
         LOG.debug('Checking existence of volume %s', volume_name)
         with self._client.open_connection() as api:
             try:
-                ssn = api.find_sc(self.configuration.dell_sc_ssn)
-                if ssn is not None:
-                    scvolume = api.find_volume(ssn,
-                                               volume_name)
+                if api.find_sc():
+                    scvolume = api.find_volume(volume_name)
             except Exception:
                 with excutils.save_and_reraise_exception():
                     LOG.error(_LE('Failed to ensure export of volume %s'),
@@ -297,10 +277,8 @@ class DellCommonDriver(san.SanDriver):
                   {'vol': volume_name, 'size': new_size})
         if volume is not None:
             with self._client.open_connection() as api:
-                ssn = api.find_sc(self.configuration.dell_sc_ssn)
-                if ssn is not None:
-                    scvolume = api.find_volume(ssn,
-                                               volume_name)
+                if api.find_sc():
+                    scvolume = api.find_volume(volume_name)
                     if api.expand_volume(scvolume, new_size) is not None:
                         return
         # If we are here nothing good happened.
@@ -320,8 +298,7 @@ class DellCommonDriver(san.SanDriver):
     def _update_volume_stats(self):
         '''Retrieve stats info from volume group.'''
         with self._client.open_connection() as api:
-            ssn = api.find_sc(self.configuration.dell_sc_ssn)
-            storageusage = api.get_storage_usage(ssn)
+            storageusage = api.get_storage_usage() if api.find_sc() else None
 
             # all of this is basically static for now
             data = {}
index 513e4779f5ed07da2f7e4ab49732c8a8352e4a71..502f21af6c39b428f083856fc208ba909fd8e9d1 100644 (file)
@@ -60,32 +60,25 @@ class DellStorageCenterFCDriver(dell_storagecenter_common.DellCommonDriver,
         LOG.debug('Initialize connection: %s', volume_name)
         with self._client.open_connection() as api:
             try:
-                ssn = api.find_sc(self.configuration.dell_sc_ssn)
                 # Find our server.
                 wwpns = connector.get('wwpns')
                 for wwn in wwpns:
-                    scserver = api.find_server(ssn,
-                                               wwn)
+                    scserver = api.find_server(wwn)
                     if scserver is not None:
                         break
 
                 # No? Create it.
                 if scserver is None:
-                    server_folder = self.configuration.dell_sc_server_folder
-                    scserver = api.create_server_multiple_hbas(ssn,
-                                                               server_folder,
-                                                               wwpns)
+                    scserver = api.create_server_multiple_hbas(wwpns)
                 # Find the volume on the storage center.
-                scvolume = api.find_volume(ssn,
-                                           volume_name)
+                scvolume = api.find_volume(volume_name)
                 if scserver is not None and scvolume is not None:
                     mapping = api.map_volume(scvolume,
                                              scserver)
                     if mapping is not None:
                         # Since we just mapped our volume we had best update
                         # our sc volume object.
-                        scvolume = api.find_volume(ssn,
-                                                   volume_name)
+                        scvolume = api.find_volume(volume_name)
                         lun, targets, init_targ_map = api.find_wwns(scvolume,
                                                                     scserver)
                         if lun is not None and len(targets) > 0:
@@ -115,17 +108,14 @@ class DellStorageCenterFCDriver(dell_storagecenter_common.DellCommonDriver,
         LOG.debug('Terminate connection: %s', volume_name)
         with self._client.open_connection() as api:
             try:
-                ssn = api.find_sc(self.configuration.dell_sc_ssn)
                 wwpns = connector.get('wwpns')
                 for wwn in wwpns:
-                    scserver = api.find_server(ssn,
-                                               wwn)
+                    scserver = api.find_server(wwn)
                     if scserver is not None:
                         break
 
                 # Find the volume on the storage center.
-                scvolume = api.find_volume(ssn,
-                                           volume_name)
+                scvolume = api.find_volume(volume_name)
                 # Get our target map so we can return it to free up a zone.
                 lun, targets, init_targ_map = api.find_wwns(scvolume,
                                                             scserver)
index 3c20ff99f3297efcdccbf6663dad24da21151d31..86623aad057be8e3a3eb477d708f781418de40c0 100644 (file)
@@ -54,19 +54,13 @@ class DellStorageCenterISCSIDriver(san.SanISCSIDriver,
 
         with self._client.open_connection() as api:
             try:
-                ssn = api.find_sc(self.configuration.dell_sc_ssn)
                 # Find our server.
-                server = api.find_server(ssn,
-                                         initiator_name)
+                server = api.find_server(initiator_name)
                 # No? Create it.
                 if server is None:
-                    server_folder = self.configuration.dell_sc_server_folder
-                    server = api.create_server(ssn,
-                                               server_folder,
-                                               initiator_name)
+                    server = api.create_server(initiator_name)
                 # Find the volume on the storage center.
-                scvolume = api.find_volume(ssn,
-                                           volume_name)
+                scvolume = api.find_volume(volume_name)
 
                 # if we have a server and a volume lets bring them together.
                 if server is not None and scvolume is not None:
@@ -75,8 +69,7 @@ class DellStorageCenterISCSIDriver(san.SanISCSIDriver,
                     if mapping is not None:
                         # Since we just mapped our volume we had best update
                         # our sc volume object.
-                        scvolume = api.find_volume(ssn,
-                                                   volume_name)
+                        scvolume = api.find_volume(volume_name)
 
                         if multipath:
                             # Just return our properties with all the mappings
@@ -136,12 +129,9 @@ class DellStorageCenterISCSIDriver(san.SanISCSIDriver,
                    'i': initiator_name})
         with self._client.open_connection() as api:
             try:
-                ssn = api.find_sc(self.configuration.dell_sc_ssn)
-                scserver = api.find_server(ssn,
-                                           initiator_name)
+                scserver = api.find_server(initiator_name)
                 # Find the volume on the storage center.
-                scvolume = api.find_volume(ssn,
-                                           volume_name)
+                scvolume = api.find_volume(volume_name)
 
                 # If we have a server and a volume lets pull them apart.
                 if (scserver is not None and