"currentControllerId": "070000000000000000000001",
"protectionInformationCapable": false, "mapped": false,
"reconPriority": 1, "protectionType":
+ "type1Protection"},
+ {"extremeProtection": false, "pitBaseVolume": true,
+ "dssMaxSegmentSize": 131072,
+ "totalSizeInBytes": "1073741824", "raidLevel": "raid6",
+ "volumeRef": "0200000060080E500023BB34000003FB515C2293",
+ "listOfMappings": [], "sectorOffset": "15",
+ "id": "0200000060080E500023BB34000003FB515C2293",
+ "wwn": "60080E500023BB3400001FC352D14CB2",
+ "capacity": "2147483648", "mgmtClientAttribute": 0,
+ "label": "CFDXJ67BLJH25DXCZFZD4NSF54",
+ "volumeFull": false,
+ "blkSize": 512, "volumeCopyTarget": false,
+ "volumeGroupRef":
+ "0400000060080E500023BB3400001F9F52CECC3F",
+ "preferredControllerId": "070000000000000000000001",
+ "currentManager": "070000000000000000000001",
+ "applicationTagOwned": false, "status": "optimal",
+ "segmentSize": 131072, "volumeUse": "standardVolume",
+ "action": "none", "preferredManager":
+ "070000000000000000000001", "volumeHandle": 15,
+ "offline": false, "preReadRedundancyCheckEnabled": false,
+ "dssPreallocEnabled": false, "name": "bdm-vc-test-1",
+ "worldWideName": "60080E500023BB3400001FC352D14CB2",
+ "currentControllerId": "070000000000000000000001",
+ "protectionInformationCapable": false, "mapped": false,
+ "reconPriority": 1, "protectionType":
"type1Protection"}]"""
elif re.match("^/storage-systems/[0-9a-zA-Z]+/volumes/[0-9A-Za-z]+$",
path):
maps = [{'lunMappingRef': 'hdkjsdhjsdh',
'mapRef': '8400000060080E500023C73400300381515BFBA3',
- 'volumeRef': 'CFDXJ67BLJH25DXCZFZD4NSF54',
+ 'volumeRef': '0200000060080E500023BB34000003FB515C2293',
'lun': 2}]
self.driver._get_host_mapping_for_vol_frm_array = mock.Mock(
return_value=maps)
self.driver._create_volume,
self.fake_eseries_pool_label,
self.fake_eseries_volume_label, self.fake_size_gb)
+
+ def test_portal_for_vol_controller(self):
+ volume = {'id': 'vol_id', 'currentManager': 'ctrl1'}
+ vol_nomatch = {'id': 'vol_id', 'currentManager': 'ctrl3'}
+ portals = [{'controller': 'ctrl2', 'iqn': 'iqn2'},
+ {'controller': 'ctrl1', 'iqn': 'iqn1'}]
+ portal = self.driver._get_iscsi_portal_for_vol(volume, portals)
+ self.assertEqual(portal, {'controller': 'ctrl1', 'iqn': 'iqn1'})
+ portal = self.driver._get_iscsi_portal_for_vol(vol_nomatch, portals)
+ self.assertEqual(portal, {'controller': 'ctrl2', 'iqn': 'iqn2'})
+
+ def test_portal_for_vol_any_false(self):
+ vol_nomatch = {'id': 'vol_id', 'currentManager': 'ctrl3'}
+ portals = [{'controller': 'ctrl2', 'iqn': 'iqn2'},
+ {'controller': 'ctrl1', 'iqn': 'iqn1'}]
+ self.assertRaises(exception.NetAppDriverException,
+ self.driver._get_iscsi_portal_for_vol,
+ vol_nomatch, portals, False)
try:
return self._get_cached_volume(label)
except KeyError:
- for vol in self._client.list_volumes():
- if vol.get('label') == label:
- self._cache_volume(vol)
- break
- return self._get_cached_volume(label)
+ return self._get_latest_volume(uid)
+
+ def _get_latest_volume(self, uid):
+ label = utils.convert_uuid_to_es_fmt(uid)
+ for vol in self._client.list_volumes():
+ if vol.get('label') == label:
+ self._cache_volume(vol)
+ return self._get_cached_volume(label)
+ raise exception.NetAppDriverException(_("Volume %s not found."), uid)
def _get_cached_volume(self, label):
vol_id = self._objects['volumes']['label_ref'][label]
def initialize_connection(self, volume, connector):
"""Allow connection to connector and return connection info."""
initiator_name = connector['initiator']
- vol = self._get_volume(volume['id'])
- iscsi_det = self._get_iscsi_service_details()
+ vol = self._get_latest_volume(volume['id'])
+ iscsi_details = self._get_iscsi_service_details()
+ iscsi_det = self._get_iscsi_portal_for_vol(vol, iscsi_details)
mapping = self._map_volume_to_host(vol, initiator_name)
lun_id = mapping['lun']
self._cache_vol_mapping(mapping)
def _get_iscsi_service_details(self):
"""Gets iscsi iqn, ip and port information."""
+ ports = []
hw_inventory = self._client.list_hardware_inventory()
iscsi_ports = hw_inventory.get('iscsiPorts')
if iscsi_ports:
iscsi_det['ip'] =\
port['ipv4Data']['ipv4AddressData']['ipv4Address']
iscsi_det['iqn'] = port['iqn']
- iscsi_det['tcp_port'] = port.get('tcpListenPort', '3260')
- return iscsi_det
- msg = _('No good iscsi portal information found for %s.')
+ iscsi_det['tcp_port'] = port.get('tcpListenPort')
+ iscsi_det['controller'] = port.get('controllerId')
+ ports.append(iscsi_det)
+ if not ports:
+ msg = _('No good iscsi portals found for %s.')
+ raise exception.NetAppDriverException(
+ msg % self._client.get_system_id())
+ return ports
+
+ def _get_iscsi_portal_for_vol(self, volume, portals, anyController=True):
+ """Get the iscsi portal info relevant to volume."""
+ for portal in portals:
+ if portal.get('controller') == volume.get('currentManager'):
+ return portal
+ if anyController and portals:
+ return portals[0]
+ msg = _('No good iscsi portal found in supplied list for %s.')
raise exception.NetAppDriverException(
msg % self._client.get_system_id())