Merge "HPE 3PAR: use vlan iscsi ips"
This commit is contained in:
commit
3b9cc13a94
@ -9003,6 +9003,75 @@ class TestHPE3PARISCSIDriver(HPE3PARBaseDriver):
|
||||
|
||||
self.assertDictEqual(self.multipath_properties, result)
|
||||
|
||||
def test_initialize_connection_multipath_vlan_ip(self):
|
||||
# setup_mock_client drive with default configuration
|
||||
# and return the mock HTTP 3PAR client
|
||||
mock_client = self.setup_driver()
|
||||
mock_client.getVolume.return_value = {'userCPG': HPE3PAR_CPG}
|
||||
mock_client.getCPG.return_value = {}
|
||||
mock_client.getHost.side_effect = [
|
||||
hpeexceptions.HTTPNotFound('fake'),
|
||||
{'name': self.FAKE_HOST}]
|
||||
mock_client.queryHost.return_value = {
|
||||
'members': [{
|
||||
'name': self.FAKE_HOST
|
||||
}]
|
||||
}
|
||||
|
||||
mock_client.getHostVLUNs.side_effect = [
|
||||
hpeexceptions.HTTPNotFound('fake'),
|
||||
[{'active': True,
|
||||
'volumeName': self.VOLUME_3PAR_NAME,
|
||||
'lun': self.TARGET_LUN, 'type': 0,
|
||||
'portPos': {'node': 8, 'slot': 1, 'cardPort': 1}}]]
|
||||
|
||||
location = ("%(volume_name)s,%(lun_id)s,%(host)s,%(nsp)s" %
|
||||
{'volume_name': self.VOLUME_3PAR_NAME,
|
||||
'lun_id': self.TARGET_LUN,
|
||||
'host': self.FAKE_HOST,
|
||||
'nsp': 'something'})
|
||||
mock_client.createVLUN.return_value = location
|
||||
|
||||
mock_client.getiSCSIPorts.return_value = [{
|
||||
'IPAddr': '1.1.1.2',
|
||||
'iSCSIName': self.TARGET_IQN,
|
||||
'iSCSIVlans': [{'IPAddr': '192.168.100.1',
|
||||
'iSCSIName': self.TARGET_IQN}]
|
||||
}]
|
||||
|
||||
with mock.patch.object(hpecommon.HPE3PARCommon,
|
||||
'_create_client') as mock_create_client:
|
||||
mock_create_client.return_value = mock_client
|
||||
volume = copy.deepcopy(self.volume)
|
||||
volume.replication_status = 'disabled'
|
||||
result = self.driver.initialize_connection(
|
||||
volume,
|
||||
self.connector_multipath_enabled)
|
||||
|
||||
expected = [
|
||||
mock.call.getVolume(self.VOLUME_3PAR_NAME),
|
||||
mock.call.getCPG(HPE3PAR_CPG),
|
||||
mock.call.getHost(self.FAKE_HOST),
|
||||
mock.call.queryHost(iqns=['iqn.1993-08.org.debian:01:222']),
|
||||
mock.call.getHost(self.FAKE_HOST),
|
||||
mock.call.getiSCSIPorts(
|
||||
state=self.mock_client_conf['PORT_STATE_READY']),
|
||||
mock.call.getHostVLUNs(self.FAKE_HOST),
|
||||
mock.call.createVLUN(
|
||||
self.VOLUME_3PAR_NAME,
|
||||
auto=True,
|
||||
hostname=self.FAKE_HOST,
|
||||
portPos=self.FAKE_ISCSI_PORT['portPos'],
|
||||
lun=None),
|
||||
mock.call.getHostVLUNs(self.FAKE_HOST)]
|
||||
|
||||
mock_client.assert_has_calls(
|
||||
self.standard_login +
|
||||
expected +
|
||||
self.standard_logout)
|
||||
|
||||
self.assertDictEqual(self.multipath_properties, result)
|
||||
|
||||
def test_terminate_connection_for_clear_chap_creds_not_found(self):
|
||||
# setup_mock_client drive with default configuration
|
||||
# and return the mock HTTP 3PAR client
|
||||
@ -10537,6 +10606,24 @@ class TestHPE3PARISCSIDriver(HPE3PARBaseDriver):
|
||||
self.driver.initialize_iscsi_ports,
|
||||
common)
|
||||
|
||||
def test_initialize_iscsi_ports_with_vlan_ip(self):
|
||||
# setup_mock_client drive with default configuration
|
||||
# and return the mock HTTP 3PAR client
|
||||
conf = self.setup_configuration()
|
||||
conf.hpe3par_iscsi_ips = ["192.168.100.1:1234"]
|
||||
mock_client = self.setup_driver(config=conf)
|
||||
|
||||
mock_client.getPorts.return_value = PORTS_VLAN_RET
|
||||
expected = [mock.call.getPorts()]
|
||||
|
||||
with mock.patch.object(hpecommon.HPE3PARCommon,
|
||||
'_create_client') as mock_create_client:
|
||||
mock_create_client.return_value = mock_client
|
||||
|
||||
common = self.driver._login()
|
||||
self.driver.initialize_iscsi_ports(common)
|
||||
mock_client.assert_has_calls(expected)
|
||||
|
||||
def test_ensure_export(self):
|
||||
# setup_mock_client drive with default configuration
|
||||
# and return the mock HTTP 3PAR client
|
||||
@ -10889,6 +10976,19 @@ PORTS_RET = ({'members':
|
||||
'HWAddr': '2C27D75375D6',
|
||||
'type': 8}]})
|
||||
|
||||
PORTS_VLAN_RET = ({'members':
|
||||
[{'portPos': {'node': 1, 'slot': 8, 'cardPort': 2},
|
||||
'protocol': 2,
|
||||
'IPAddr': '10.10.220.252',
|
||||
'linkState': 4,
|
||||
'device': [],
|
||||
'iSCSIName': 'iqn.2000-05.com.3pardata:21820002ac00383d',
|
||||
'mode': 2,
|
||||
'HWAddr': '2C27D75375D2',
|
||||
'type': 8,
|
||||
'iSCSIVlans': [{'IPAddr': '192.168.100.1'}],
|
||||
}]})
|
||||
|
||||
VLUNS1_RET = ({'members':
|
||||
[{'portPos': {'node': 1, 'slot': 8, 'cardPort': 2},
|
||||
'hostname': 'foo', 'active': True},
|
||||
|
@ -129,10 +129,11 @@ class HPE3PARISCSIDriver(hpebasedriver.HPE3PARDriverBase):
|
||||
4.0.4 - Added Peer Persistence feature
|
||||
4.0.5 - Added Primera array check. bug #1849525
|
||||
4.0.6 - Allow iSCSI support for Primera 4.2 onwards
|
||||
4.0.7 - Use vlan iscsi ips. Bug #2015034
|
||||
|
||||
"""
|
||||
|
||||
VERSION = "4.0.6"
|
||||
VERSION = "4.0.7"
|
||||
|
||||
# The name of the CI wiki page.
|
||||
CI_WIKI_NAME = "HPE_Storage_CI"
|
||||
@ -164,6 +165,13 @@ class HPE3PARISCSIDriver(hpebasedriver.HPE3PARDriverBase):
|
||||
finally:
|
||||
self._logout(common)
|
||||
|
||||
def _update_dicts(self, temp_iscsi_ip, iscsi_ip_list, ip, port):
|
||||
ip_port = temp_iscsi_ip[ip]['ip_port']
|
||||
iscsi_ip_list[ip] = {'ip_port': ip_port,
|
||||
'nsp': port['nsp'],
|
||||
'iqn': port['iSCSIName']}
|
||||
del temp_iscsi_ip[ip]
|
||||
|
||||
def initialize_iscsi_ports(self, common,
|
||||
remote_target=None, remote_client=None):
|
||||
# map iscsi_ip-> ip_port
|
||||
@ -202,15 +210,20 @@ class HPE3PARISCSIDriver(hpebasedriver.HPE3PARDriverBase):
|
||||
# when found, add the valid iSCSI ip, ip port, iqn and nsp
|
||||
# to the iSCSI IP dictionary
|
||||
iscsi_ports = common.get_active_iscsi_target_ports(remote_client)
|
||||
LOG.debug("iscsi_ports: %(iscsi_ports)s", {'iscsi_ports': iscsi_ports})
|
||||
|
||||
for port in iscsi_ports:
|
||||
ip = port['IPAddr']
|
||||
if ip in temp_iscsi_ip:
|
||||
ip_port = temp_iscsi_ip[ip]['ip_port']
|
||||
iscsi_ip_list[ip] = {'ip_port': ip_port,
|
||||
'nsp': port['nsp'],
|
||||
'iqn': port['iSCSIName']}
|
||||
del temp_iscsi_ip[ip]
|
||||
self._update_dicts(temp_iscsi_ip, iscsi_ip_list, ip, port)
|
||||
|
||||
if 'iSCSIVlans' in port:
|
||||
for vip in port['iSCSIVlans']:
|
||||
ip = vip['IPAddr']
|
||||
if ip in temp_iscsi_ip:
|
||||
LOG.debug("vlan ip: %(ip)s", {'ip': ip})
|
||||
self._update_dicts(temp_iscsi_ip, iscsi_ip_list,
|
||||
ip, port)
|
||||
|
||||
# if the single value iscsi_ip_address option is still in the
|
||||
# temp dictionary it's because it defaults to $my_ip which doesn't
|
||||
@ -237,6 +250,44 @@ class HPE3PARISCSIDriver(hpebasedriver.HPE3PARDriverBase):
|
||||
self.iscsi_ips[common._client_conf['hpe3par_api_url']] = (
|
||||
iscsi_ip_list)
|
||||
|
||||
def _vlun_create_or_use_existing(self, volume, common, host, iscsi_ips,
|
||||
target_portals, target_iqns,
|
||||
target_luns, remote_client,
|
||||
target_portal_ips,
|
||||
existing_vluns, iscsi_ip,
|
||||
lun_id, port):
|
||||
vlun = None
|
||||
# check for an already existing VLUN matching the
|
||||
# nsp for this iSCSI IP. If one is found, use it
|
||||
# instead of creating a new VLUN.
|
||||
for v in existing_vluns:
|
||||
portPos = common.build_portPos(
|
||||
iscsi_ips[iscsi_ip]['nsp'])
|
||||
if v['portPos'] == portPos:
|
||||
vlun = v
|
||||
break
|
||||
else:
|
||||
vlun = common.create_vlun(
|
||||
volume, host, iscsi_ips[iscsi_ip]['nsp'],
|
||||
lun_id=lun_id, remote_client=remote_client)
|
||||
|
||||
# This function is called multiple times (from a for loop).
|
||||
# We want to use the same LUN ID for every port.
|
||||
# For first port, lun_id is received as None.
|
||||
# - assign lun_id = vlun['lun'] and return it.
|
||||
# Thus for subsequent ports, that same lun_id is used
|
||||
# in create_vlun() above.
|
||||
if lun_id is None:
|
||||
lun_id = vlun['lun']
|
||||
|
||||
iscsi_ip_port = "%s:%s" % (
|
||||
iscsi_ip, iscsi_ips[iscsi_ip]['ip_port'])
|
||||
target_portals.append(iscsi_ip_port)
|
||||
target_iqns.append(port['iSCSIName'])
|
||||
target_luns.append(vlun['lun'])
|
||||
|
||||
return lun_id
|
||||
|
||||
def _initialize_connection_common(self, volume, connector, common,
|
||||
host, iscsi_ips, ready_ports,
|
||||
target_portals, target_iqns, target_luns,
|
||||
@ -255,30 +306,30 @@ class HPE3PARISCSIDriver(hpebasedriver.HPE3PARDriverBase):
|
||||
for port in ready_ports:
|
||||
iscsi_ip = port['IPAddr']
|
||||
if iscsi_ip in target_portal_ips:
|
||||
vlun = None
|
||||
# check for an already existing VLUN matching the
|
||||
# nsp for this iSCSI IP. If one is found, use it
|
||||
# instead of creating a new VLUN.
|
||||
for v in existing_vluns:
|
||||
portPos = common.build_portPos(
|
||||
iscsi_ips[iscsi_ip]['nsp'])
|
||||
if v['portPos'] == portPos:
|
||||
vlun = v
|
||||
break
|
||||
else:
|
||||
vlun = common.create_vlun(
|
||||
volume, host, iscsi_ips[iscsi_ip]['nsp'],
|
||||
lun_id=lun_id, remote_client=remote_client)
|
||||
lun_id = (
|
||||
self._vlun_create_or_use_existing(
|
||||
volume, common, host, iscsi_ips,
|
||||
target_portals, target_iqns,
|
||||
target_luns, remote_client,
|
||||
target_portal_ips,
|
||||
existing_vluns, iscsi_ip,
|
||||
lun_id, port))
|
||||
|
||||
# We want to use the same LUN ID for every port
|
||||
if lun_id is None:
|
||||
lun_id = vlun['lun']
|
||||
if 'iSCSIVlans' in port:
|
||||
for vip in port['iSCSIVlans']:
|
||||
iscsi_ip = vip['IPAddr']
|
||||
if iscsi_ip in target_portal_ips:
|
||||
LOG.debug("vlan ip: %(ip)s", {'ip': iscsi_ip})
|
||||
|
||||
lun_id = (
|
||||
self._vlun_create_or_use_existing(
|
||||
volume, common, host, iscsi_ips,
|
||||
target_portals, target_iqns,
|
||||
target_luns, remote_client,
|
||||
target_portal_ips,
|
||||
existing_vluns, iscsi_ip,
|
||||
lun_id, port))
|
||||
|
||||
iscsi_ip_port = "%s:%s" % (
|
||||
iscsi_ip, iscsi_ips[iscsi_ip]['ip_port'])
|
||||
target_portals.append(iscsi_ip_port)
|
||||
target_iqns.append(port['iSCSIName'])
|
||||
target_luns.append(vlun['lun'])
|
||||
else:
|
||||
LOG.warning("iSCSI IP: '%s' was not found in "
|
||||
"hpe3par_iscsi_ips list defined in "
|
||||
|
@ -0,0 +1,5 @@
|
||||
fixes:
|
||||
- |
|
||||
HPE 3PAR driver `Bug #2015034 <https://bugs.launchpad.net/cinder/+bug/2015034>`_:
|
||||
Added handling for VLAN iscsi IPs in the 3PAR iSCSI driver.
|
||||
|
Loading…
x
Reference in New Issue
Block a user