]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
EMC VMAX - Incorrect SG selected on an VMAX3 attach
authorHelen Walsh <helen.walsh@emc.com>
Thu, 26 Nov 2015 15:29:06 +0000 (15:29 +0000)
committerHelen Walsh <helen.walsh@emc.com>
Mon, 18 Jan 2016 10:14:32 +0000 (10:14 +0000)
Use the default storage group for an SLO/Workload
combination and not the storage group that will be
part of the Masking View(contains the host name).

Change-Id: I195dd0113103930af6e54e19afeebf33f979e8fa
Closes-Bug: #1515176

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

index ec62c58818714c5e502422c76b751a4814585df0..29088b3c1ebb7c3fca17370f982d18577c4a67c1 100644 (file)
@@ -7174,3 +7174,67 @@ class EMCVMAXProvisionV3Test(test.TestCase):
             provisionv3.extend_volume_in_SG, conn, storageConfigService,
             theVolumeInstanceName, inVolumeInstanceName, volumeSize,
             extraSpecs)
+
+
+class EMCVMAXMaskingTest(test.TestCase):
+    def setUp(self):
+        self.data = EMCVMAXCommonData()
+
+        super(EMCVMAXMaskingTest, self).setUp()
+
+        configuration = mock.Mock()
+        configuration.safe_get.return_value = 'MaskingTests'
+        configuration.config_group = 'MaskingTests'
+        emc_vmax_common.EMCVMAXCommon._get_ecom_connection = mock.Mock(
+            return_value=self.fake_ecom_connection())
+        emc_vmax_common.EMCVMAXCommon._gather_info = mock.Mock(
+            return_value=self.fake_gather_info())
+        instancename = FakeCIMInstanceName()
+        emc_vmax_utils.EMCVMAXUtils.get_instance_name = (
+            instancename.fake_getinstancename)
+        driver = emc_vmax_iscsi.EMCVMAXISCSIDriver(configuration=configuration)
+        driver.db = FakeDB()
+        self.driver = driver
+        self.driver.utils = emc_vmax_utils.EMCVMAXUtils(object)
+
+    def fake_ecom_connection(self):
+        conn = FakeEcomConnection()
+        return conn
+
+    def fake_gather_info(self):
+        return
+
+    def test_get_v3_default_storage_group_instance_name(self):
+        masking = self.driver.common.masking
+        conn = self.fake_ecom_connection()
+        extraSpecs = self.data.extra_specs
+        masking._get_and_remove_from_storage_group_v3 = mock.Mock()
+        controllerConfigService = (
+            self.driver.utils.find_controller_configuration_service(
+                conn, self.data.storage_system))
+        maskingviewdict = self.driver.common._populate_masking_dict(
+            self.data.test_volume, self.data.connector, extraSpecs)
+        result = (
+            masking._get_v3_default_storagegroup_instancename(
+                conn, maskingviewdict['volumeInstance'],
+                maskingviewdict,
+                controllerConfigService, maskingviewdict['volumeName']))
+        self.assertEqual('OS-SRP_1-Bronze-DSS-SG', result['ElementName'])
+
+    def test_get_v3_default_storage_group_instance_name_warning(self):
+        masking = self.driver.common.masking
+        conn = self.fake_ecom_connection()
+        extraSpecs = self.data.extra_specs
+        masking.utils.get_storage_groups_from_volume = mock.Mock(
+            return_value=[])
+        controllerConfigService = (
+            self.driver.utils.find_controller_configuration_service(
+                conn, self.data.storage_system))
+        maskingviewdict = self.driver.common._populate_masking_dict(
+            self.data.test_volume, self.data.connector, extraSpecs)
+        result = (
+            masking._get_v3_default_storagegroup_instancename(
+                conn, maskingviewdict['volumeInstance'],
+                maskingviewdict,
+                controllerConfigService, maskingviewdict['volumeName']))
+        self.assertIsNone(result)
index 690faadd68c42c24cfcdd2cedb828b551191e8b3..b909561c16edc32e5b30a196ff7efd6bbf03759b 100644 (file)
@@ -49,6 +49,7 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver):
               - Proper error handling for invalid SLOs (bug #1512795)
               - Extend Volume for VMAX3, SE8.1.0.3
               https://blueprints.launchpad.net/cinder/+spec/vmax3-extend-volume
+              - Incorrect SG selected on an attach (#1515176)
     """
 
     VERSION = "2.3.0"
index 97525de782f0cee356d3af3f5b4d849946d686e0..489ae583be480e031f2b88f6daf5f5d77661b002 100644 (file)
@@ -57,6 +57,7 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
               - Proper error handling for invalid SLOs (bug #1512795)
               - Extend Volume for VMAX3, SE8.1.0.3
               https://blueprints.launchpad.net/cinder/+spec/vmax3-extend-volume
+              - Incorrect SG selected on an attach (#1515176)
     """
 
     VERSION = "2.3.0"
index f0627f0ae0f1dcbed1ec3cf37710dbd6e9371ffd..b4b595bbc2d8d8d67a5b05a79a55d52a48d21ed6 100644 (file)
@@ -91,30 +91,11 @@ class EMCVMAXMasking(object):
         assocStorageGroupName = None
         if isLiveMigration is False:
             if isV3:
-                assocStorageGroupInstanceName = (
-                    self.utils.get_storage_group_from_volume(
-                        conn, volumeInstance.path,
-                        maskingViewDict['sgGroupName']))
-                instance = conn.GetInstance(
-                    assocStorageGroupInstanceName, LocalOnly=False)
-                assocStorageGroupName = instance['ElementName']
-                defaultSgGroupName = self.utils.get_v3_storage_group_name(
-                    maskingViewDict['pool'],
-                    maskingViewDict['slo'],
-                    maskingViewDict['workload'])
-
-                if assocStorageGroupName != defaultSgGroupName:
-                    LOG.warning(_LW(
-                        "Volume: %(volumeName)s Does not belong "
-                        "to storage storage group %(defaultSgGroupName)s."),
-                        {'volumeName': volumeName,
-                         'defaultSgGroupName': defaultSgGroupName})
-                defaultStorageGroupInstanceName = assocStorageGroupInstanceName
-
-                self._get_and_remove_from_storage_group_v3(
-                    conn, controllerConfigService, volumeInstance.path,
-                    volumeName, maskingViewDict,
-                    defaultStorageGroupInstanceName)
+                defaultStorageGroupInstanceName = (
+                    self._get_v3_default_storagegroup_instancename(
+                        conn, volumeInstance, maskingViewDict,
+                        controllerConfigService, volumeName))
+
             else:
                 fastPolicyName = maskingViewDict['fastPolicy']
                 # If FAST is enabled remove the volume from the default SG.
@@ -191,6 +172,41 @@ class EMCVMAXMasking(object):
 
         return rollbackDict
 
+    def _get_v3_default_storagegroup_instancename(self, conn, volumeinstance,
+                                                  maskingviewdict,
+                                                  controllerConfigService,
+                                                  volumeName):
+        defaultStorageGroupInstanceName = None
+        defaultSgGroupName = self.utils.get_v3_storage_group_name(
+            maskingviewdict['pool'],
+            maskingviewdict['slo'],
+            maskingviewdict['workload'])
+        assocStorageGroupInstanceNames = (
+            self.utils.get_storage_groups_from_volume(
+                conn, volumeinstance.path))
+        for assocStorageGroupInstanceName in (
+                assocStorageGroupInstanceNames):
+            instance = conn.GetInstance(
+                assocStorageGroupInstanceName, LocalOnly=False)
+            assocStorageGroupName = instance['ElementName']
+
+            if assocStorageGroupName == defaultSgGroupName:
+                defaultStorageGroupInstanceName = (
+                    assocStorageGroupInstanceName)
+                break
+        if defaultStorageGroupInstanceName:
+            self._get_and_remove_from_storage_group_v3(
+                conn, controllerConfigService, volumeinstance.path,
+                volumeName, maskingviewdict,
+                defaultStorageGroupInstanceName)
+        else:
+            LOG.warning(_LW(
+                "Volume: %(volumeName)s does not belong "
+                "to storage group %(defaultSgGroupName)s."),
+                {'volumeName': volumeName,
+                 'defaultSgGroupName': defaultSgGroupName})
+        return defaultStorageGroupInstanceName
+
     def _validate_masking_view(self, conn, maskingViewDict,
                                defaultStorageGroupInstanceName,
                                extraSpecs):