Merge "VMAX driver - Removal of iscsiadm from vmax cinder"
This commit is contained in:
commit
781475f114
@ -17,7 +17,6 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
|
||||||
import unittest
|
import unittest
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
|
|
||||||
@ -159,6 +158,13 @@ class Fake_CIMProperty(object):
|
|||||||
cimproperty.value = '10.10.10.10'
|
cimproperty.value = '10.10.10.10'
|
||||||
return cimproperty
|
return cimproperty
|
||||||
|
|
||||||
|
def fake_getiqn(self):
|
||||||
|
cimproperty = Fake_CIMProperty()
|
||||||
|
cimproperty.key = 'Name'
|
||||||
|
cimproperty.value = (
|
||||||
|
'iqn.1992-04.com.emc:600009700bca30c01b9c012000000003,t,0x0001')
|
||||||
|
return cimproperty
|
||||||
|
|
||||||
def fake_getSupportedReplicationTypesCIMProperty(self, reptypes):
|
def fake_getSupportedReplicationTypesCIMProperty(self, reptypes):
|
||||||
cimproperty = Fake_CIMProperty()
|
cimproperty = Fake_CIMProperty()
|
||||||
if reptypes == 'V3':
|
if reptypes == 'V3':
|
||||||
@ -1725,6 +1731,17 @@ class FakeEcomConnection(object):
|
|||||||
ipprotocolendpoint.properties = properties
|
ipprotocolendpoint.properties = properties
|
||||||
ipprotocolendpoint.path = ipprotocolendpoint
|
ipprotocolendpoint.path = ipprotocolendpoint
|
||||||
ipprotocolendpoints.append(ipprotocolendpoint)
|
ipprotocolendpoints.append(ipprotocolendpoint)
|
||||||
|
iqnprotocolendpoint = CIM_IPProtocolEndpoint()
|
||||||
|
iqnprotocolendpoint['CreationClassName'] = (
|
||||||
|
'Symm_VirtualiSCSIProtocolEndpoint')
|
||||||
|
iqnprotocolendpoint['SystemName'] = self.data.storage_system
|
||||||
|
classcimproperty = Fake_CIMProperty()
|
||||||
|
iqncimproperty = (
|
||||||
|
classcimproperty.fake_getiqn())
|
||||||
|
properties = {u'Name': iqncimproperty}
|
||||||
|
iqnprotocolendpoint.properties = properties
|
||||||
|
iqnprotocolendpoint.path = iqnprotocolendpoint
|
||||||
|
ipprotocolendpoints.append(iqnprotocolendpoint)
|
||||||
return ipprotocolendpoints
|
return ipprotocolendpoints
|
||||||
|
|
||||||
def _default_enum(self):
|
def _default_enum(self):
|
||||||
@ -1754,16 +1771,11 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase):
|
|||||||
True,
|
True,
|
||||||
'volume_backend_name':
|
'volume_backend_name':
|
||||||
'ISCSINoFAST'}))
|
'ISCSINoFAST'}))
|
||||||
self.mock_object(emc_vmax_iscsi.EMCVMAXISCSIDriver,
|
|
||||||
'smis_do_iscsi_discovery',
|
|
||||||
self.fake_do_iscsi_discovery)
|
|
||||||
self.mock_object(emc_vmax_common.EMCVMAXCommon, '_get_ecom_connection',
|
self.mock_object(emc_vmax_common.EMCVMAXCommon, '_get_ecom_connection',
|
||||||
self.fake_ecom_connection)
|
self.fake_ecom_connection)
|
||||||
instancename = FakeCIMInstanceName()
|
instancename = FakeCIMInstanceName()
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
||||||
instancename.fake_getinstancename)
|
instancename.fake_getinstancename)
|
||||||
self.mock_object(time, 'sleep',
|
|
||||||
self.fake_sleep)
|
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
||||||
self.fake_is_v3)
|
self.fake_is_v3)
|
||||||
driver = emc_vmax_iscsi.EMCVMAXISCSIDriver(configuration=configuration)
|
driver = emc_vmax_iscsi.EMCVMAXISCSIDriver(configuration=configuration)
|
||||||
@ -1936,17 +1948,6 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase):
|
|||||||
conn = FakeEcomConnection()
|
conn = FakeEcomConnection()
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
def fake_do_iscsi_discovery(self, volume):
|
|
||||||
output = []
|
|
||||||
properties = {}
|
|
||||||
properties['target_portal'] = '10.10.0.50:3260'
|
|
||||||
properties['target_iqn'] = 'iqn.1992-04.com.emc:50000973f006dd80'
|
|
||||||
output.append(properties)
|
|
||||||
return output
|
|
||||||
|
|
||||||
def fake_sleep(self, seconds):
|
|
||||||
return
|
|
||||||
|
|
||||||
def fake_is_v3(self, conn, serialNumber):
|
def fake_is_v3(self, conn, serialNumber):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -2178,9 +2179,9 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase):
|
|||||||
|
|
||||||
def test_find_ip_protocol_endpoints(self):
|
def test_find_ip_protocol_endpoints(self):
|
||||||
conn = self.fake_ecom_connection()
|
conn = self.fake_ecom_connection()
|
||||||
foundIpAddresses = self.driver.common._find_ip_protocol_endpoints(
|
endpoint = self.driver.common._find_ip_protocol_endpoints(
|
||||||
conn, self.data.storage_system, self.data.port_group)
|
conn, self.data.storage_system, self.data.port_group)
|
||||||
self.assertEqual('10.10.10.10', foundIpAddresses[0])
|
self.assertEqual('10.10.10.10', endpoint[0]['ip'])
|
||||||
|
|
||||||
def test_find_device_number(self):
|
def test_find_device_number(self):
|
||||||
host = 'fakehost'
|
host = 'fakehost'
|
||||||
@ -3954,17 +3955,11 @@ class EMCVMAXISCSIDriverFastTestCase(test.TestCase):
|
|||||||
configuration.cinder_emc_config_file = self.config_file_path
|
configuration.cinder_emc_config_file = self.config_file_path
|
||||||
configuration.safe_get.return_value = 'ISCSIFAST'
|
configuration.safe_get.return_value = 'ISCSIFAST'
|
||||||
configuration.config_group = 'ISCSIFAST'
|
configuration.config_group = 'ISCSIFAST'
|
||||||
|
|
||||||
self.mock_object(emc_vmax_iscsi.EMCVMAXISCSIDriver,
|
|
||||||
'smis_do_iscsi_discovery',
|
|
||||||
self.fake_do_iscsi_discovery)
|
|
||||||
self.mock_object(emc_vmax_common.EMCVMAXCommon, '_get_ecom_connection',
|
self.mock_object(emc_vmax_common.EMCVMAXCommon, '_get_ecom_connection',
|
||||||
self.fake_ecom_connection)
|
self.fake_ecom_connection)
|
||||||
instancename = FakeCIMInstanceName()
|
instancename = FakeCIMInstanceName()
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
||||||
instancename.fake_getinstancename)
|
instancename.fake_getinstancename)
|
||||||
self.mock_object(time, 'sleep',
|
|
||||||
self.fake_sleep)
|
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
||||||
self.fake_is_v3)
|
self.fake_is_v3)
|
||||||
driver = emc_vmax_iscsi.EMCVMAXISCSIDriver(configuration=configuration)
|
driver = emc_vmax_iscsi.EMCVMAXISCSIDriver(configuration=configuration)
|
||||||
@ -4041,17 +4036,6 @@ class EMCVMAXISCSIDriverFastTestCase(test.TestCase):
|
|||||||
conn = FakeEcomConnection()
|
conn = FakeEcomConnection()
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
def fake_do_iscsi_discovery(self, volume):
|
|
||||||
output = []
|
|
||||||
properties = {}
|
|
||||||
properties['target_portal'] = '10.10.0.50:3260'
|
|
||||||
properties['target_iqn'] = 'iqn.1992-04.com.emc:50000973f006dd80'
|
|
||||||
output.append(properties)
|
|
||||||
return output
|
|
||||||
|
|
||||||
def fake_sleep(self, seconds):
|
|
||||||
return
|
|
||||||
|
|
||||||
def fake_is_v3(self, conn, serialNumber):
|
def fake_is_v3(self, conn, serialNumber):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -4613,8 +4597,6 @@ class EMCVMAXFCDriverNoFastTestCase(test.TestCase):
|
|||||||
instancename = FakeCIMInstanceName()
|
instancename = FakeCIMInstanceName()
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
||||||
instancename.fake_getinstancename)
|
instancename.fake_getinstancename)
|
||||||
self.mock_object(time, 'sleep',
|
|
||||||
self.fake_sleep)
|
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
||||||
self.fake_is_v3)
|
self.fake_is_v3)
|
||||||
|
|
||||||
@ -4686,9 +4668,6 @@ class EMCVMAXFCDriverNoFastTestCase(test.TestCase):
|
|||||||
conn = FakeEcomConnection()
|
conn = FakeEcomConnection()
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
def fake_sleep(self, seconds):
|
|
||||||
return
|
|
||||||
|
|
||||||
def fake_is_v3(self, conn, serialNumber):
|
def fake_is_v3(self, conn, serialNumber):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -5180,8 +5159,6 @@ class EMCVMAXFCDriverFastTestCase(test.TestCase):
|
|||||||
instancename = FakeCIMInstanceName()
|
instancename = FakeCIMInstanceName()
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
||||||
instancename.fake_getinstancename)
|
instancename.fake_getinstancename)
|
||||||
self.mock_object(time, 'sleep',
|
|
||||||
self.fake_sleep)
|
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
||||||
self.fake_is_v3)
|
self.fake_is_v3)
|
||||||
driver = emc_vmax_fc.EMCVMAXFCDriver(configuration=configuration)
|
driver = emc_vmax_fc.EMCVMAXFCDriver(configuration=configuration)
|
||||||
@ -5258,9 +5235,6 @@ class EMCVMAXFCDriverFastTestCase(test.TestCase):
|
|||||||
conn = FakeEcomConnection()
|
conn = FakeEcomConnection()
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
def fake_sleep(self, seconds):
|
|
||||||
return
|
|
||||||
|
|
||||||
def fake_is_v3(self, conn, serialNumber):
|
def fake_is_v3(self, conn, serialNumber):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -5846,8 +5820,6 @@ class EMCV3DriverTestCase(test.TestCase):
|
|||||||
instancename = FakeCIMInstanceName()
|
instancename = FakeCIMInstanceName()
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
||||||
instancename.fake_getinstancename)
|
instancename.fake_getinstancename)
|
||||||
self.mock_object(time, 'sleep',
|
|
||||||
self.fake_sleep)
|
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
||||||
self.fake_is_v3)
|
self.fake_is_v3)
|
||||||
self.patcher = mock.patch(
|
self.patcher = mock.patch(
|
||||||
@ -5930,9 +5902,6 @@ class EMCV3DriverTestCase(test.TestCase):
|
|||||||
self.conn = FakeEcomConnection()
|
self.conn = FakeEcomConnection()
|
||||||
return self.conn
|
return self.conn
|
||||||
|
|
||||||
def fake_sleep(self, seconds):
|
|
||||||
return
|
|
||||||
|
|
||||||
def fake_is_v3(self, conn, serialNumber):
|
def fake_is_v3(self, conn, serialNumber):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -6699,19 +6668,13 @@ class EMCV2MultiPoolDriverTestCase(test.TestCase):
|
|||||||
configuration.cinder_emc_config_file = self.config_file_path
|
configuration.cinder_emc_config_file = self.config_file_path
|
||||||
configuration.config_group = 'MULTI_POOL'
|
configuration.config_group = 'MULTI_POOL'
|
||||||
|
|
||||||
self.mock_object(emc_vmax_iscsi.EMCVMAXISCSIDriver,
|
|
||||||
'smis_do_iscsi_discovery',
|
|
||||||
self.fake_do_iscsi_discovery)
|
|
||||||
self.mock_object(emc_vmax_common.EMCVMAXCommon, '_get_ecom_connection',
|
self.mock_object(emc_vmax_common.EMCVMAXCommon, '_get_ecom_connection',
|
||||||
self.fake_ecom_connection)
|
self.fake_ecom_connection)
|
||||||
instancename = FakeCIMInstanceName()
|
instancename = FakeCIMInstanceName()
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
||||||
instancename.fake_getinstancename)
|
instancename.fake_getinstancename)
|
||||||
self.mock_object(time, 'sleep',
|
|
||||||
self.fake_sleep)
|
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
||||||
self.fake_is_v3)
|
self.fake_is_v3)
|
||||||
|
|
||||||
driver = emc_vmax_iscsi.EMCVMAXISCSIDriver(configuration=configuration)
|
driver = emc_vmax_iscsi.EMCVMAXISCSIDriver(configuration=configuration)
|
||||||
driver.db = FakeDB()
|
driver.db = FakeDB()
|
||||||
self.driver = driver
|
self.driver = driver
|
||||||
@ -6799,17 +6762,6 @@ class EMCV2MultiPoolDriverTestCase(test.TestCase):
|
|||||||
self.conn = FakeEcomConnection()
|
self.conn = FakeEcomConnection()
|
||||||
return self.conn
|
return self.conn
|
||||||
|
|
||||||
def fake_do_iscsi_discovery(self, volume):
|
|
||||||
output = []
|
|
||||||
properties = {}
|
|
||||||
properties['target_portal'] = '10.10.0.50:3260'
|
|
||||||
properties['target_iqn'] = 'iqn.1992-04.com.emc:50000973f006dd80'
|
|
||||||
output.append(properties)
|
|
||||||
return output
|
|
||||||
|
|
||||||
def fake_sleep(self, seconds):
|
|
||||||
return
|
|
||||||
|
|
||||||
def fake_is_v3(self, conn, serialNumber):
|
def fake_is_v3(self, conn, serialNumber):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -6993,8 +6945,6 @@ class EMCV3MultiSloDriverTestCase(test.TestCase):
|
|||||||
instancename = FakeCIMInstanceName()
|
instancename = FakeCIMInstanceName()
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
||||||
instancename.fake_getinstancename)
|
instancename.fake_getinstancename)
|
||||||
self.mock_object(time, 'sleep',
|
|
||||||
self.fake_sleep)
|
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
||||||
self.fake_is_v3)
|
self.fake_is_v3)
|
||||||
|
|
||||||
@ -7096,9 +7046,6 @@ class EMCV3MultiSloDriverTestCase(test.TestCase):
|
|||||||
self.conn = FakeEcomConnection()
|
self.conn = FakeEcomConnection()
|
||||||
return self.conn
|
return self.conn
|
||||||
|
|
||||||
def fake_sleep(self, seconds):
|
|
||||||
return
|
|
||||||
|
|
||||||
def fake_is_v3(self, conn, serialNumber):
|
def fake_is_v3(self, conn, serialNumber):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -7300,8 +7247,6 @@ class EMCV2MultiPoolDriverMultipleEcomsTestCase(test.TestCase):
|
|||||||
instancename = FakeCIMInstanceName()
|
instancename = FakeCIMInstanceName()
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'get_instance_name',
|
||||||
instancename.fake_getinstancename)
|
instancename.fake_getinstancename)
|
||||||
self.mock_object(time, 'sleep',
|
|
||||||
self.fake_sleep)
|
|
||||||
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
self.mock_object(emc_vmax_utils.EMCVMAXUtils, 'isArrayV3',
|
||||||
self.fake_is_v3)
|
self.fake_is_v3)
|
||||||
driver = emc_vmax_fc.EMCVMAXFCDriver(configuration=configuration)
|
driver = emc_vmax_fc.EMCVMAXFCDriver(configuration=configuration)
|
||||||
@ -7456,9 +7401,6 @@ class EMCV2MultiPoolDriverMultipleEcomsTestCase(test.TestCase):
|
|||||||
self.conn = FakeEcomConnection()
|
self.conn = FakeEcomConnection()
|
||||||
return self.conn
|
return self.conn
|
||||||
|
|
||||||
def fake_sleep(self, seconds):
|
|
||||||
return
|
|
||||||
|
|
||||||
def fake_is_v3(self, conn, serialNumber):
|
def fake_is_v3(self, conn, serialNumber):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -8268,6 +8210,13 @@ class EMCVMAXUtilsTest(test.TestCase):
|
|||||||
os.remove(emc_vmax_utils.LIVE_MIGRATION_FILE)
|
os.remove(emc_vmax_utils.LIVE_MIGRATION_FILE)
|
||||||
shutil.rmtree(tempdir)
|
shutil.rmtree(tempdir)
|
||||||
|
|
||||||
|
def test_get_iqn(self):
|
||||||
|
conn = FakeEcomConnection()
|
||||||
|
iqn = "iqn.1992-04.com.emc:600009700bca30c01b9c012000000003,t,0x0001"
|
||||||
|
ipprotocolendpoints = conn._enum_ipprotocolendpoint()
|
||||||
|
foundIqn = self.driver.utils.get_iqn(conn, ipprotocolendpoints[1])
|
||||||
|
self.assertEqual(iqn, foundIqn)
|
||||||
|
|
||||||
|
|
||||||
class EMCVMAXCommonTest(test.TestCase):
|
class EMCVMAXCommonTest(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -8381,6 +8330,20 @@ class EMCVMAXCommonTest(test.TestCase):
|
|||||||
self.driver.common._cleanup_target(
|
self.driver.common._cleanup_target(
|
||||||
repServiceInstanceName, targetInstance, extraSpecs)
|
repServiceInstanceName, targetInstance, extraSpecs)
|
||||||
|
|
||||||
|
def test_get_ip_and_iqn(self):
|
||||||
|
conn = FakeEcomConnection()
|
||||||
|
endpoint = {}
|
||||||
|
ipprotocolendpoints = conn._enum_ipprotocolendpoint()
|
||||||
|
ip_and_iqn = self.driver.common.get_ip_and_iqn(conn, endpoint,
|
||||||
|
ipprotocolendpoints[0])
|
||||||
|
ip_and_iqn = self.driver.common.get_ip_and_iqn(conn, endpoint,
|
||||||
|
ipprotocolendpoints[1])
|
||||||
|
self.assertEqual(
|
||||||
|
'iqn.1992-04.com.emc:600009700bca30c01b9c012000000003,t,0x0001',
|
||||||
|
ip_and_iqn['iqn'])
|
||||||
|
self.assertEqual(
|
||||||
|
'10.10.10.10', ip_and_iqn['ip'])
|
||||||
|
|
||||||
|
|
||||||
class EMCVMAXProvisionTest(test.TestCase):
|
class EMCVMAXProvisionTest(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -8464,42 +8427,22 @@ class EMCVMAXISCSITest(test.TestCase):
|
|||||||
configuration = mock.Mock()
|
configuration = mock.Mock()
|
||||||
configuration.safe_get.return_value = 'iSCSITests'
|
configuration.safe_get.return_value = 'iSCSITests'
|
||||||
configuration.config_group = 'iSCSITests'
|
configuration.config_group = 'iSCSITests'
|
||||||
self.mock_object(emc_vmax_iscsi.EMCVMAXISCSIDriver,
|
|
||||||
'smis_do_iscsi_discovery',
|
|
||||||
self.fake_do_iscsi_discovery)
|
|
||||||
emc_vmax_common.EMCVMAXCommon._gather_info = mock.Mock()
|
emc_vmax_common.EMCVMAXCommon._gather_info = mock.Mock()
|
||||||
driver = emc_vmax_iscsi.EMCVMAXISCSIDriver(configuration=configuration)
|
driver = emc_vmax_iscsi.EMCVMAXISCSIDriver(configuration=configuration)
|
||||||
driver.db = FakeDB()
|
driver.db = FakeDB()
|
||||||
self.driver = driver
|
self.driver = driver
|
||||||
|
|
||||||
def fake_do_iscsi_discovery(self, volume):
|
|
||||||
output = []
|
|
||||||
properties = {}
|
|
||||||
properties['target_portal'] = '10.10.0.50:3260'
|
|
||||||
properties['target_iqn'] = 'iqn.1992-04.com.emc:50000973f006dd80'
|
|
||||||
output.append(properties)
|
|
||||||
properties = {}
|
|
||||||
properties['target_portal'] = '10.10.0.51:3260'
|
|
||||||
properties['target_iqn'] = 'iqn.1992-04.com.emc:50000973f006dd81'
|
|
||||||
output.append(properties)
|
|
||||||
return output
|
|
||||||
|
|
||||||
def test_parse_target_list(self):
|
|
||||||
targets = ["10.10.10.31:3260,0 iqn.1f:29.ID2",
|
|
||||||
"10.10.10.32:3260,0 iqn.2f:29.ID2"]
|
|
||||||
out_targets = self.driver._parse_target_list(targets)
|
|
||||||
self.assertEqual('10.10.10.31:3260', out_targets[0]['target_portal'])
|
|
||||||
self.assertEqual('iqn.1f:29.ID2', out_targets[0]['target_iqn'])
|
|
||||||
self.assertEqual('10.10.10.32:3260', out_targets[1]['target_portal'])
|
|
||||||
self.assertEqual('iqn.2f:29.ID2', out_targets[1]['target_iqn'])
|
|
||||||
|
|
||||||
def test_smis_get_iscsi_properties(self):
|
def test_smis_get_iscsi_properties(self):
|
||||||
self.driver.iscsi_ip_addresses = ['10.10.0.50', '10.10.0.51']
|
|
||||||
device_info = {'hostlunid': 1}
|
device_info = {'hostlunid': 1}
|
||||||
self.driver.common.find_device_number = (
|
self.driver.common.find_device_number = (
|
||||||
mock.Mock(return_value=device_info))
|
mock.Mock(return_value=device_info))
|
||||||
|
iqns_and_ips = (
|
||||||
|
[{'iqn': 'iqn.1992-04.com.emc:50000973f006dd80,t,0x0001',
|
||||||
|
'ip': '10.10.0.50'},
|
||||||
|
{'iqn': 'iqn.1992-04.com.emc:50000973f006dd81,t,0x0001',
|
||||||
|
'ip': '10.10.0.51'}])
|
||||||
properties = self.driver.smis_get_iscsi_properties(
|
properties = self.driver.smis_get_iscsi_properties(
|
||||||
self.data.test_volume, self.data.connector, True)
|
self.data.test_volume, self.data.connector, iqns_and_ips, True)
|
||||||
self.assertEqual([1, 1], properties['target_luns'])
|
self.assertEqual([1, 1], properties['target_luns'])
|
||||||
self.assertEqual(['iqn.1992-04.com.emc:50000973f006dd80',
|
self.assertEqual(['iqn.1992-04.com.emc:50000973f006dd80',
|
||||||
'iqn.1992-04.com.emc:50000973f006dd81'],
|
'iqn.1992-04.com.emc:50000973f006dd81'],
|
||||||
|
@ -432,7 +432,7 @@ class EMCVMAXCommon(object):
|
|||||||
volume, connector, extraSpecs, maskingViewDict))
|
volume, connector, extraSpecs, maskingViewDict))
|
||||||
|
|
||||||
if self.protocol.lower() == 'iscsi':
|
if self.protocol.lower() == 'iscsi':
|
||||||
deviceInfoDict['iscsi_ip_addresses'] = (
|
deviceInfoDict['ip_and_iqn'] = (
|
||||||
self._find_ip_protocol_endpoints(
|
self._find_ip_protocol_endpoints(
|
||||||
self.conn, deviceInfoDict['storagesystem'],
|
self.conn, deviceInfoDict['storagesystem'],
|
||||||
portGroupName))
|
portGroupName))
|
||||||
@ -4484,12 +4484,12 @@ class EMCVMAXCommon(object):
|
|||||||
ipendpointinstancenames = (
|
ipendpointinstancenames = (
|
||||||
self.utils.get_ip_protocol_endpoints(
|
self.utils.get_ip_protocol_endpoints(
|
||||||
conn, tcpendpointinstancename))
|
conn, tcpendpointinstancename))
|
||||||
|
endpoint = {}
|
||||||
for ipendpointinstancename in ipendpointinstancenames:
|
for ipendpointinstancename in ipendpointinstancenames:
|
||||||
ipaddress = (
|
endpoint = self.get_ip_and_iqn(conn, endpoint,
|
||||||
self.utils.get_iscsi_ip_address(
|
ipendpointinstancename)
|
||||||
conn, ipendpointinstancename))
|
if bool(endpoint):
|
||||||
if ipaddress:
|
foundipaddresses.append(endpoint)
|
||||||
foundipaddresses.append(ipaddress)
|
|
||||||
return foundipaddresses
|
return foundipaddresses
|
||||||
|
|
||||||
def _extend_v3_volume(self, volumeInstance, volumeName, newSize,
|
def _extend_v3_volume(self, volumeInstance, volumeName, newSize,
|
||||||
@ -4538,3 +4538,26 @@ class EMCVMAXCommon(object):
|
|||||||
{'sourceVol': sourceInstance.path,
|
{'sourceVol': sourceInstance.path,
|
||||||
'targetVol': targetInstance.path})
|
'targetVol': targetInstance.path})
|
||||||
return targetInstance
|
return targetInstance
|
||||||
|
|
||||||
|
def get_ip_and_iqn(self, conn, endpoint, ipendpointinstancename):
|
||||||
|
"""Get ip and iqn from the endpoint.
|
||||||
|
|
||||||
|
:param conn: ecom connection
|
||||||
|
:param endpoint: end point
|
||||||
|
:param ipendpointinstancename: ip endpoint
|
||||||
|
:returns: endpoint
|
||||||
|
"""
|
||||||
|
if ('iSCSIProtocolEndpoint' in six.text_type(
|
||||||
|
ipendpointinstancename['CreationClassName'])):
|
||||||
|
iqn = self.utils.get_iqn(conn, ipendpointinstancename)
|
||||||
|
if iqn:
|
||||||
|
endpoint['iqn'] = iqn
|
||||||
|
elif ('IPProtocolEndpoint' in six.text_type(
|
||||||
|
ipendpointinstancename['CreationClassName'])):
|
||||||
|
ipaddress = (
|
||||||
|
self.utils.get_iscsi_ip_address(
|
||||||
|
conn, ipendpointinstancename))
|
||||||
|
if ipaddress:
|
||||||
|
endpoint['ip'] = ipaddress
|
||||||
|
|
||||||
|
return endpoint
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
ISCSI Drivers for EMC VMAX arrays based on SMI-S.
|
ISCSI Drivers for EMC VMAX arrays based on SMI-S.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import os
|
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
import six
|
import six
|
||||||
|
|
||||||
@ -93,7 +91,6 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
|
|||||||
emc_vmax_common.EMCVMAXCommon('iSCSI',
|
emc_vmax_common.EMCVMAXCommon('iSCSI',
|
||||||
self.VERSION,
|
self.VERSION,
|
||||||
configuration=self.configuration))
|
configuration=self.configuration))
|
||||||
self.iscsi_ip_addresses = []
|
|
||||||
|
|
||||||
def check_for_setup_error(self):
|
def check_for_setup_error(self):
|
||||||
pass
|
pass
|
||||||
@ -194,17 +191,16 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
|
|||||||
device_info = self.common.initialize_connection(
|
device_info = self.common.initialize_connection(
|
||||||
volume, connector)
|
volume, connector)
|
||||||
try:
|
try:
|
||||||
self.iscsi_ip_addresses = device_info['iscsi_ip_addresses']
|
ip_and_iqn = device_info['ip_and_iqn']
|
||||||
is_multipath = device_info['is_multipath']
|
is_multipath = device_info['is_multipath']
|
||||||
except KeyError as ex:
|
except KeyError as ex:
|
||||||
exception_message = (_("Cannot get iSCSI ipaddresses or "
|
exception_message = (_("Cannot get iSCSI ipaddresses or "
|
||||||
"multipath flag. Exception is %(ex)s. ")
|
"multipath flag. Exception is %(ex)s. ")
|
||||||
% {'ex': ex})
|
% {'ex': ex})
|
||||||
|
|
||||||
raise exception.VolumeBackendAPIException(data=exception_message)
|
raise exception.VolumeBackendAPIException(data=exception_message)
|
||||||
|
|
||||||
iscsi_properties = self.smis_get_iscsi_properties(
|
iscsi_properties = self.smis_get_iscsi_properties(
|
||||||
volume, connector, is_multipath)
|
volume, connector, ip_and_iqn, is_multipath)
|
||||||
|
|
||||||
LOG.info(_LI("Leaving initialize_connection: %s"), iscsi_properties)
|
LOG.info(_LI("Leaving initialize_connection: %s"), iscsi_properties)
|
||||||
return {
|
return {
|
||||||
@ -212,50 +208,6 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
|
|||||||
'data': iscsi_properties
|
'data': iscsi_properties
|
||||||
}
|
}
|
||||||
|
|
||||||
def _call_iscsiadm(self, iscsi_ip_address):
|
|
||||||
"""Calls iscsiadm with iscsi ip address"""
|
|
||||||
try:
|
|
||||||
(out, _err) = self._execute('iscsiadm', '-m', 'discovery',
|
|
||||||
'-t', 'sendtargets', '-p',
|
|
||||||
iscsi_ip_address,
|
|
||||||
run_as_root=True)
|
|
||||||
return out, _err, None
|
|
||||||
except Exception as ex:
|
|
||||||
return None, None, ex
|
|
||||||
|
|
||||||
def smis_do_iscsi_discovery(self, volume):
|
|
||||||
"""Calls iscsiadm with each iscsi ip address in the list"""
|
|
||||||
LOG.info(_LI("ISCSI provider_location not stored, using discovery."))
|
|
||||||
targets = []
|
|
||||||
if len(self.iscsi_ip_addresses) == 0:
|
|
||||||
LOG.error(_LE("The list of iscsi_ip_addresses is empty"))
|
|
||||||
return targets
|
|
||||||
outList = []
|
|
||||||
for iscsi_ip_address in self.iscsi_ip_addresses:
|
|
||||||
if iscsi_ip_address:
|
|
||||||
out, _err, ex = self._call_iscsiadm(iscsi_ip_address)
|
|
||||||
if out:
|
|
||||||
outList.append(out)
|
|
||||||
|
|
||||||
if len(outList) == 0:
|
|
||||||
if ex:
|
|
||||||
exception_message = (_("Unsuccessful iscsiadm. "
|
|
||||||
"Exception is %(ex)s. ")
|
|
||||||
% {'ex': ex})
|
|
||||||
else:
|
|
||||||
exception_message = (_("iscsiadm execution failed. "))
|
|
||||||
raise exception.VolumeBackendAPIException(data=exception_message)
|
|
||||||
|
|
||||||
LOG.info(_LI(
|
|
||||||
"smis_do_iscsi_discovery is: %(out)s."),
|
|
||||||
{'out': out})
|
|
||||||
for out in outList:
|
|
||||||
for target in out.splitlines():
|
|
||||||
targets.append(target)
|
|
||||||
|
|
||||||
outTargets = self._parse_target_list(targets)
|
|
||||||
return outTargets
|
|
||||||
|
|
||||||
def _parse_target_list(self, targets):
|
def _parse_target_list(self, targets):
|
||||||
"""Parse target list into usable format.
|
"""Parse target list into usable format.
|
||||||
|
|
||||||
@ -271,7 +223,8 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
|
|||||||
outTargets.append(properties)
|
outTargets.append(properties)
|
||||||
return outTargets
|
return outTargets
|
||||||
|
|
||||||
def smis_get_iscsi_properties(self, volume, connector, is_multipath):
|
def smis_get_iscsi_properties(self, volume, connector, ip_and_iqn,
|
||||||
|
is_multipath):
|
||||||
"""Gets iscsi configuration.
|
"""Gets iscsi configuration.
|
||||||
|
|
||||||
We ideally get saved information in the volume entity, but fall back
|
We ideally get saved information in the volume entity, but fall back
|
||||||
@ -288,14 +241,6 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
|
|||||||
meaning use CHAP with the specified credentials.
|
meaning use CHAP with the specified credentials.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
targets = self.smis_do_iscsi_discovery(volume)
|
|
||||||
if len(targets) == 0:
|
|
||||||
raise exception.InvalidVolume(_("Could not find iSCSI export "
|
|
||||||
"for volume %(volumeName)s.")
|
|
||||||
% {'volumeName': volume['name']})
|
|
||||||
|
|
||||||
LOG.debug("ISCSI Discovery: Found %s", targets)
|
|
||||||
|
|
||||||
device_info = self.common.find_device_number(
|
device_info = self.common.find_device_number(
|
||||||
volume, connector['host'])
|
volume, connector['host'])
|
||||||
|
|
||||||
@ -315,28 +260,18 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
|
|||||||
% {'volumeName': volume['name']})
|
% {'volumeName': volume['name']})
|
||||||
raise exception.VolumeBackendAPIException(data=exception_message)
|
raise exception.VolumeBackendAPIException(data=exception_message)
|
||||||
|
|
||||||
properties = {'target_discovered': False,
|
properties = {}
|
||||||
'target_iqn': 'unknown',
|
if len(ip_and_iqn) > 1 and is_multipath:
|
||||||
'target_iqns': None,
|
properties['target_portals'] = ([t['ip'] + ":3260" for t in
|
||||||
'target_portal': 'unknown',
|
ip_and_iqn])
|
||||||
'target_portals': None,
|
properties['target_iqns'] = ([t['iqn'].split(",")[0] for t in
|
||||||
'target_lun': 'unknown',
|
ip_and_iqn])
|
||||||
'target_luns': None,
|
properties['target_luns'] = [lun_id] * len(ip_and_iqn)
|
||||||
'volume_id': volume['id']}
|
properties['target_discovered'] = True
|
||||||
|
properties['target_iqn'] = ip_and_iqn[0]['iqn'].split(",")[0]
|
||||||
if len(self.iscsi_ip_addresses) > 0:
|
properties['target_portal'] = ip_and_iqn[0]['ip'] + ":3260"
|
||||||
if len(self.iscsi_ip_addresses) > 1 and is_multipath:
|
properties['target_lun'] = lun_id
|
||||||
properties['target_iqns'] = [t['target_iqn'] for t in targets]
|
properties['volume_id'] = volume['id']
|
||||||
properties['target_portals'] = (
|
|
||||||
[t['target_portal'] for t in targets])
|
|
||||||
properties['target_luns'] = [lun_id] * len(targets)
|
|
||||||
properties['target_discovered'] = True
|
|
||||||
properties['target_iqn'] = [t['target_iqn'] for t in targets][0]
|
|
||||||
properties['target_portal'] = (
|
|
||||||
[t['target_portal'] for t in targets][0])
|
|
||||||
properties['target_lun'] = lun_id
|
|
||||||
else:
|
|
||||||
LOG.error(_LE('Failed to find available iSCSI targets.'))
|
|
||||||
|
|
||||||
LOG.info(_LI(
|
LOG.info(_LI(
|
||||||
"ISCSI properties: %(properties)s."), {'properties': properties})
|
"ISCSI properties: %(properties)s."), {'properties': properties})
|
||||||
@ -425,17 +360,6 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
|
|||||||
"""Deletes a cgsnapshot."""
|
"""Deletes a cgsnapshot."""
|
||||||
return self.common.delete_cgsnapshot(context, cgsnapshot, snapshots)
|
return self.common.delete_cgsnapshot(context, cgsnapshot, snapshots)
|
||||||
|
|
||||||
def _check_for_iscsi_ip_address(self):
|
|
||||||
"""Check to see if iscsi_ip_address is set in cinder.conf
|
|
||||||
|
|
||||||
:returns: boolean -- True if iscsi_ip_address id defined in config.
|
|
||||||
"""
|
|
||||||
bExists = os.path.exists(CINDER_CONF)
|
|
||||||
if bExists:
|
|
||||||
if 'iscsi_ip_address' in open(CINDER_CONF).read():
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def manage_existing(self, volume, external_ref):
|
def manage_existing(self, volume, external_ref):
|
||||||
"""Manages an existing VMAX Volume (import to Cinder).
|
"""Manages an existing VMAX Volume (import to Cinder).
|
||||||
|
|
||||||
|
@ -2796,3 +2796,19 @@ class EMCVMAXUtils(object):
|
|||||||
"record.",
|
"record.",
|
||||||
{'Volume': volume['id']})
|
{'Volume': volume['id']})
|
||||||
return returned_record
|
return returned_record
|
||||||
|
|
||||||
|
def get_iqn(self, conn, ipendpointinstancename):
|
||||||
|
"""Get the IPv4Address from the ip endpoint instance name.
|
||||||
|
|
||||||
|
:param conn: the ecom connection
|
||||||
|
:param ipendpointinstancename: the ip endpoint instance name
|
||||||
|
:returns: foundIqn
|
||||||
|
"""
|
||||||
|
foundIqn = None
|
||||||
|
ipendpointinstance = conn.GetInstance(ipendpointinstancename)
|
||||||
|
propertiesList = ipendpointinstance.properties.items()
|
||||||
|
for properties in propertiesList:
|
||||||
|
if properties[0] == 'Name':
|
||||||
|
cimProperties = properties[1]
|
||||||
|
foundIqn = cimProperties.value
|
||||||
|
return foundIqn
|
||||||
|
Loading…
Reference in New Issue
Block a user