]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Error handling for invalid SLO/Workload combo
authorHelen Walsh <helen.walsh@emc.com>
Thu, 5 Nov 2015 13:33:34 +0000 (13:33 +0000)
committerHelen Walsh <helen.walsh@emc.com>
Thu, 17 Dec 2015 20:28:23 +0000 (20:28 +0000)
This fix checks the VMAX3 to see if the user inputted SLO/workload
combination is valid. If it is not, a explanatory exception is
thrown.

Closes-Bug: #1512795

Change-Id: Ic55830eef96788eff8f6ab141a60e1dcfb9971b8

cinder/tests/unit/test_emc_vmax.py
cinder/volume/drivers/emc/emc_vmax_common.py
cinder/volume/drivers/emc/emc_vmax_fc.py
cinder/volume/drivers/emc/emc_vmax_iscsi.py
cinder/volume/drivers/emc/emc_vmax_provision_v3.py

index 3e7d510c38fd60056a80ab93ed30657c3d181115..d42e9eff47584031e54b05acc46227970f6dd026 100644 (file)
@@ -1466,7 +1466,7 @@ class FakeEcomConnection(object):
         storagesetting = {}
         storagesetting['CreationClassName'] = 'CIM_StoragePoolSetting'
         storagesetting['InstanceID'] = ('SYMMETRIX-+-000197200056-+-SBronze:'
-                                        'NONE-+-F-+-0-+-SR-+-SRP_1')
+                                        'DSS-+-F-+-0-+-SR-+-SRP_1')
         storagesettings.append(storagesetting)
         return storagesettings
 
@@ -5615,6 +5615,12 @@ class EMCV3DriverTestCase(test.TestCase):
             self, _mock_volume_type, mock_storage_system):
         v3_vol = self.data.test_volume_v3
         v3_vol['host'] = 'HostX@Backend#NONE+SRP_1+1234567891011'
+        instid = 'SYMMETRIX-+-000197200056-+-NONE:DSS-+-F-+-0-+-SR-+-SRP_1'
+        storagepoolsetting = (
+            {'InstanceID': instid,
+             'CreationClassName': 'CIM_StoragePoolSetting'})
+        self.driver.common.provisionv3.get_storage_pool_setting = mock.Mock(
+            return_value=storagepoolsetting)
         extraSpecs = {'storagetype:pool': 'SRP_1',
                       'volume_backend_name': 'V3_BE',
                       'storagetype:workload': 'DSS',
@@ -6975,3 +6981,51 @@ class EMCV2MultiPoolDriverMultipleEcomsTestCase(test.TestCase):
         if bExists:
             os.remove(self.config_file_path)
         shutil.rmtree(self.tempdir)
+
+
+class EMCVMAXProvisionV3Test(test.TestCase):
+    def setUp(self):
+        self.data = EMCVMAXCommonData()
+
+        super(EMCVMAXProvisionV3Test, self).setUp()
+
+        configuration = mock.Mock()
+        configuration.safe_get.return_value = 'ProvisionV3Tests'
+        configuration.config_group = 'ProvisionV3Tests'
+        emc_vmax_common.EMCVMAXCommon._gather_info = mock.Mock()
+        driver = emc_vmax_iscsi.EMCVMAXISCSIDriver(configuration=configuration)
+        driver.db = FakeDB()
+        self.driver = driver
+
+    def test_get_storage_pool_setting(self):
+        provisionv3 = self.driver.common.provisionv3
+        conn = FakeEcomConnection()
+        slo = 'Bronze'
+        workload = 'DSS'
+        poolInstanceName = {}
+        poolInstanceName['InstanceID'] = "SATA_GOLD1"
+        poolInstanceName['CreationClassName'] = (
+            self.data.storagepool_creationclass)
+
+        storagePoolCapability = provisionv3.get_storage_pool_capability(
+            conn, poolInstanceName)
+        storagepoolsetting = provisionv3.get_storage_pool_setting(
+            conn, storagePoolCapability, slo, workload)
+        self.assertTrue(
+            'Bronze:DSS' in storagepoolsetting['InstanceID'])
+
+    def test_get_storage_pool_setting_exception(self):
+        provisionv3 = self.driver.common.provisionv3
+        conn = FakeEcomConnection()
+        slo = 'Bronze'
+        workload = 'NONE'
+        poolInstanceName = {}
+        poolInstanceName['InstanceID'] = "SATA_GOLD1"
+        poolInstanceName['CreationClassName'] = (
+            self.data.storagepool_creationclass)
+
+        storagePoolCapability = provisionv3.get_storage_pool_capability(
+            conn, poolInstanceName)
+        self.assertRaises(exception.VolumeBackendAPIException,
+                          provisionv3.get_storage_pool_setting,
+                          conn, storagePoolCapability, slo, workload)
index 928e0cd6c36f456fa9b06d870b2fc3501405cc45..27b21c31095b23dd432624d57586298e1af9d116 100644 (file)
@@ -2838,6 +2838,19 @@ class EMCVMAXCommon(object):
         poolInstanceName, storageSystemName = (
             self._get_pool_and_storage_system(extraSpecs))
 
+        # Check to see if SLO and Workload are configured on the array.
+        storagePoolCapability = self.provisionv3.get_storage_pool_capability(
+            self.conn, poolInstanceName)
+        if storagePoolCapability:
+            self.provisionv3.get_storage_pool_setting(
+                self.conn, storagePoolCapability, extraSpecs[SLO],
+                extraSpecs[WORKLOAD])
+        else:
+            exceptionMessage = (_(
+                "Cannot determine storage pool settings."))
+            LOG.error(exceptionMessage)
+            raise exception.VolumeBackendAPIException(data=exceptionMessage)
+
         LOG.debug("Create Volume: %(volume)s  Pool: %(pool)s "
                   "Storage System: %(storageSystem)s "
                   "Size: %(size)lu.",
index 4b3a286ed2109cd504879e4f620c4d8a3877c154..cf33cc6fbe630524ffa82edc596e9936749a0161 100644 (file)
@@ -46,6 +46,7 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver):
               - Fix for randomly choosing port group. (bug #1501919)
               - get_short_host_name needs to be called in find_device_number
                 (bug #1520635)
+              - Proper error handling for invalid SLOs (bug #1512795)
     """
 
     VERSION = "2.3.0"
index 605aef1cfa97534991275db8803538cd6a08d131..878a268499d6a975447e579b9733acf6816b04de 100644 (file)
@@ -54,6 +54,7 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
               - Fix for randomly choosing port group. (bug #1501919)
               - get_short_host_name needs to be called in find_device_number
                 (bug #1520635)
+              - Proper error handling for invalid SLOs (bug #1512795)
     """
 
     VERSION = "2.3.0"
index a8a6d366b69dc9c8d5992c627e55330a545cb7a2..dc8442e1c6e5536a216a3ebb8fe09e26600c97e1 100644 (file)
@@ -316,7 +316,7 @@ class EMCVMAXProvisionV3(object):
 
         return foundStorageGroupInstanceName
 
-    def _get_storage_pool_capability(self, conn, poolInstanceName):
+    def get_storage_pool_capability(self, conn, poolInstanceName):
         """Get the pool capability.
 
         :param conn: the connection information to the ecom server
@@ -334,7 +334,7 @@ class EMCVMAXProvisionV3(object):
 
         return storagePoolCapability
 
-    def _get_storage_pool_setting(
+    def get_storage_pool_setting(
             self, conn, storagePoolCapability, slo, workload):
         """Get the pool setting for pool capability.
 
@@ -358,6 +358,16 @@ class EMCVMAXProvisionV3(object):
             if matchString in settingInstanceID:
                 foundStoragePoolSetting = storagePoolSetting
                 break
+        if foundStoragePoolSetting is None:
+            exceptionMessage = (_(
+                "The array does not support the storage pool setting "
+                "for SLO %(slo)s and workload %(workload)s.  Please "
+                "check the array for valid SLOs and workloads.")
+                % {'slo': slo,
+                   'workload': workload})
+            LOG.error(exceptionMessage)
+            raise exception.VolumeBackendAPIException(
+                data=exceptionMessage)
         return foundStoragePoolSetting
 
     def _get_supported_size_range_for_SLO(
@@ -416,15 +426,14 @@ class EMCVMAXProvisionV3(object):
         :returns: supportedSizeDict
         """
         supportedSizeDict = {}
-        storagePoolCapabilityInstanceName = self._get_storage_pool_capability(
+        storagePoolCapabilityInstanceName = self.get_storage_pool_capability(
             conn, poolInstanceName)
         if storagePoolCapabilityInstanceName:
-            storagePoolSettingInstanceName = self._get_storage_pool_setting(
+            storagePoolSettingInstanceName = self.get_storage_pool_setting(
                 conn, storagePoolCapabilityInstanceName, slo, workload)
-            if storagePoolCapabilityInstanceName:
-                supportedSizeDict = self._get_supported_size_range_for_SLO(
-                    conn, storageConfigService, poolInstanceName,
-                    storagePoolSettingInstanceName, extraSpecs)
+            supportedSizeDict = self._get_supported_size_range_for_SLO(
+                conn, storageConfigService, poolInstanceName,
+                storagePoolSettingInstanceName, extraSpecs)
         return supportedSizeDict
 
     def activate_snap_relationship(