VMAX Driver - SnapVX licensing checks for VMAX3
Additional checks to see if the appropriate license is installed for the snapVx functionality in VMAX3 snapshots. Change-Id: Ib7efb76c7c890a1197f4a5f721039fec507f5b97 Closes-Bug: #1587017
This commit is contained in:
parent
af7bfedc51
commit
eeab576e89
@ -158,6 +158,20 @@ class Fake_CIMProperty(object):
|
|||||||
cimproperty.value = '10.10.10.10'
|
cimproperty.value = '10.10.10.10'
|
||||||
return cimproperty
|
return cimproperty
|
||||||
|
|
||||||
|
def fake_getSupportedReplicationTypesCIMProperty(self, reptypes):
|
||||||
|
cimproperty = Fake_CIMProperty()
|
||||||
|
if reptypes == 'V3':
|
||||||
|
cimproperty.value = [6, 7]
|
||||||
|
elif reptypes == 'V3_SYNC':
|
||||||
|
cimproperty.value = [6]
|
||||||
|
elif reptypes == 'V3_ASYNC':
|
||||||
|
cimproperty.value = [7]
|
||||||
|
elif reptypes == 'V2':
|
||||||
|
cimproperty.value = [10]
|
||||||
|
else:
|
||||||
|
cimproperty.value = [2, 3, 4, 5]
|
||||||
|
return cimproperty
|
||||||
|
|
||||||
|
|
||||||
class Fake_CIM_TierPolicyServiceCapabilities(object):
|
class Fake_CIM_TierPolicyServiceCapabilities(object):
|
||||||
|
|
||||||
@ -6031,6 +6045,8 @@ class EMCV3DriverTestCase(test.TestCase):
|
|||||||
common = self.driver.common
|
common = self.driver.common
|
||||||
common.provisionv3.utils.get_v3_default_sg_instance_name = mock.Mock(
|
common.provisionv3.utils.get_v3_default_sg_instance_name = mock.Mock(
|
||||||
return_value=(None, None, self.data.default_sg_instance_name))
|
return_value=(None, None, self.data.default_sg_instance_name))
|
||||||
|
common.utils.is_clone_licensed = (
|
||||||
|
mock.Mock(return_value=True))
|
||||||
common._initial_setup = mock.Mock(
|
common._initial_setup = mock.Mock(
|
||||||
return_value=self.default_extraspec())
|
return_value=self.default_extraspec())
|
||||||
self.driver.create_snapshot(self.data.test_volume_v3)
|
self.driver.create_snapshot(self.data.test_volume_v3)
|
||||||
@ -6078,6 +6094,8 @@ class EMCV3DriverTestCase(test.TestCase):
|
|||||||
cloneVol['BlockSize'] = self.data.block_size
|
cloneVol['BlockSize'] = self.data.block_size
|
||||||
cloneVol['host'] = self.data.fake_host_v3
|
cloneVol['host'] = self.data.fake_host_v3
|
||||||
common = self.driver.common
|
common = self.driver.common
|
||||||
|
common.utils.is_clone_licensed = (
|
||||||
|
mock.Mock(return_value=True))
|
||||||
common._initial_setup = mock.Mock(
|
common._initial_setup = mock.Mock(
|
||||||
return_value=self.default_extraspec())
|
return_value=self.default_extraspec())
|
||||||
common._get_or_create_storage_group_v3 = mock.Mock(
|
common._get_or_create_storage_group_v3 = mock.Mock(
|
||||||
@ -6390,6 +6408,8 @@ class EMCV3DriverTestCase(test.TestCase):
|
|||||||
self.data.test_volume['volume_name'] = "vmax-1234567"
|
self.data.test_volume['volume_name'] = "vmax-1234567"
|
||||||
e = exception.VolumeBackendAPIException('CreateElementReplica Ex')
|
e = exception.VolumeBackendAPIException('CreateElementReplica Ex')
|
||||||
common = self.driver.common
|
common = self.driver.common
|
||||||
|
common.utils.is_clone_licensed = (
|
||||||
|
mock.Mock(return_value=True))
|
||||||
volumeDict = {'classname': u'Symm_StorageVolume',
|
volumeDict = {'classname': u'Symm_StorageVolume',
|
||||||
'keybindings': EMCVMAXCommonData.keybindings}
|
'keybindings': EMCVMAXCommonData.keybindings}
|
||||||
common._create_v3_volume = (
|
common._create_v3_volume = (
|
||||||
@ -7826,6 +7846,7 @@ class EMCVMAXFCTest(test.TestCase):
|
|||||||
self.assertEqual(0, len(mvInstances))
|
self.assertEqual(0, len(mvInstances))
|
||||||
|
|
||||||
|
|
||||||
|
@ddt.ddt
|
||||||
class EMCVMAXUtilsTest(test.TestCase):
|
class EMCVMAXUtilsTest(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.data = EMCVMAXCommonData()
|
self.data = EMCVMAXCommonData()
|
||||||
@ -7889,6 +7910,40 @@ class EMCVMAXUtilsTest(test.TestCase):
|
|||||||
emc_vmax_provision.COPY_ON_WRITE, extraSpecs)
|
emc_vmax_provision.COPY_ON_WRITE, extraSpecs)
|
||||||
self.assertIsNotNone(rsdInstance)
|
self.assertIsNotNone(rsdInstance)
|
||||||
|
|
||||||
|
def getinstance_capability(self, reptypes):
|
||||||
|
repservicecap = CIM_ReplicationServiceCapabilities()
|
||||||
|
repservicecap['CreationClassName'] = (
|
||||||
|
'CIM_ReplicationServiceCapabilities')
|
||||||
|
|
||||||
|
classcimproperty = Fake_CIMProperty()
|
||||||
|
supportedReplicationTypes = (
|
||||||
|
classcimproperty.fake_getSupportedReplicationTypesCIMProperty(
|
||||||
|
reptypes))
|
||||||
|
properties = {u'SupportedReplicationTypes': supportedReplicationTypes}
|
||||||
|
repservicecap.properties = properties
|
||||||
|
return repservicecap
|
||||||
|
|
||||||
|
@ddt.data(('V3', True), ('V3_ASYNC', True), ('V3_SYNC', True),
|
||||||
|
('V2', False))
|
||||||
|
@ddt.unpack
|
||||||
|
def test_is_clone_licensed(self, reptypes, isV3):
|
||||||
|
conn = FakeEcomConnection()
|
||||||
|
capabilityInstanceName = self.getinstance_capability(reptypes)
|
||||||
|
conn.GetInstance = mock.Mock(
|
||||||
|
return_value=capabilityInstanceName)
|
||||||
|
self.assertTrue(self.driver.utils.is_clone_licensed(
|
||||||
|
conn, capabilityInstanceName, isV3))
|
||||||
|
|
||||||
|
def test_is_clone_licensed_false(self):
|
||||||
|
conn = FakeEcomConnection()
|
||||||
|
isV3 = True
|
||||||
|
reptypes = None
|
||||||
|
capabilityInstanceName = self.getinstance_capability(reptypes)
|
||||||
|
conn.GetInstance = mock.Mock(
|
||||||
|
return_value=capabilityInstanceName)
|
||||||
|
self.assertFalse(self.driver.utils.is_clone_licensed(
|
||||||
|
conn, capabilityInstanceName, isV3))
|
||||||
|
|
||||||
|
|
||||||
class EMCVMAXCommonTest(test.TestCase):
|
class EMCVMAXCommonTest(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -2068,7 +2068,7 @@ class EMCVMAXCommon(object):
|
|||||||
self.utils.find_replication_service_capabilities(self.conn,
|
self.utils.find_replication_service_capabilities(self.conn,
|
||||||
storageSystem))
|
storageSystem))
|
||||||
is_clone_license = self.utils.is_clone_licensed(
|
is_clone_license = self.utils.is_clone_licensed(
|
||||||
self.conn, repServCapabilityInstanceName)
|
self.conn, repServCapabilityInstanceName, extraSpecs[ISV3])
|
||||||
|
|
||||||
if is_clone_license is False:
|
if is_clone_license is False:
|
||||||
exceptionMessage = (_(
|
exceptionMessage = (_(
|
||||||
|
@ -67,10 +67,12 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver):
|
|||||||
- Replacement of EMCGetTargetEndpoints api (bug #1512791)
|
- Replacement of EMCGetTargetEndpoints api (bug #1512791)
|
||||||
- VMAX3 snapvx improvements (bug #1522821)
|
- VMAX3 snapvx improvements (bug #1522821)
|
||||||
- Operations and timeout issues (bug #1538214)
|
- Operations and timeout issues (bug #1538214)
|
||||||
|
2.4.0 - EMC VMAX - locking SG for concurrent threads (bug #1554634)
|
||||||
|
- SnapVX licensing checks for VMAX3 (bug #1587017)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = "2.3.0"
|
VERSION = "2.4.0"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
||||||
|
@ -73,10 +73,12 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
|
|||||||
- Replacement of EMCGetTargetEndpoints api (bug #1512791)
|
- Replacement of EMCGetTargetEndpoints api (bug #1512791)
|
||||||
- VMAX3 snapvx improvements (bug #1522821)
|
- VMAX3 snapvx improvements (bug #1522821)
|
||||||
- Operations and timeout issues (bug #1538214)
|
- Operations and timeout issues (bug #1538214)
|
||||||
|
2.4.0 - EMC VMAX - locking SG for concurrent threads (bug #1554634)
|
||||||
|
- SnapVX licensing checks for VMAX3 (bug #1587017)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = "2.3.0"
|
VERSION = "2.4.0"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@ except ImportError:
|
|||||||
STORAGEGROUPTYPE = 4
|
STORAGEGROUPTYPE = 4
|
||||||
POSTGROUPTYPE = 3
|
POSTGROUPTYPE = 3
|
||||||
CLONE_REPLICATION_TYPE = 10
|
CLONE_REPLICATION_TYPE = 10
|
||||||
|
SYNC_SNAPSHOT_LOCAL = 6
|
||||||
|
ASYNC_SNAPSHOT_LOCAL = 7
|
||||||
MAX_POOL_LENGTH = 16
|
MAX_POOL_LENGTH = 16
|
||||||
MAX_FASTPOLICY_LENGTH = 14
|
MAX_FASTPOLICY_LENGTH = 14
|
||||||
|
|
||||||
@ -1692,7 +1694,7 @@ class EMCVMAXUtils(object):
|
|||||||
|
|
||||||
return foundRepServCapability
|
return foundRepServCapability
|
||||||
|
|
||||||
def is_clone_licensed(self, conn, capabilityInstanceName):
|
def is_clone_licensed(self, conn, capabilityInstanceName, isV3):
|
||||||
"""Check if the clone feature is licensed and enabled.
|
"""Check if the clone feature is licensed and enabled.
|
||||||
|
|
||||||
:param conn: the connection to the ecom server
|
:param conn: the connection to the ecom server
|
||||||
@ -1709,10 +1711,19 @@ class EMCVMAXUtils(object):
|
|||||||
LOG.debug("Found supported replication types: "
|
LOG.debug("Found supported replication types: "
|
||||||
"%(repTypes)s",
|
"%(repTypes)s",
|
||||||
{'repTypes': repTypes})
|
{'repTypes': repTypes})
|
||||||
if CLONE_REPLICATION_TYPE in repTypes:
|
if isV3:
|
||||||
# Clone is a supported replication type.
|
if (SYNC_SNAPSHOT_LOCAL in repTypes or
|
||||||
LOG.debug("Clone is licensed and enabled.")
|
ASYNC_SNAPSHOT_LOCAL in repTypes):
|
||||||
return True
|
# Snapshot is a supported replication type.
|
||||||
|
LOG.debug("Snapshot for VMAX3 is licensed and "
|
||||||
|
"enabled.")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
if CLONE_REPLICATION_TYPE in repTypes:
|
||||||
|
# Clone is a supported replication type.
|
||||||
|
LOG.debug("Clone for VMAX2 is licensed and "
|
||||||
|
"enabled.")
|
||||||
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def create_storage_hardwareId_instance_name(
|
def create_storage_hardwareId_instance_name(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user