def wwpns(self): """Builds the WWPNs of the adapters that will connect the ports.""" # Refresh the instance. It could have been updated by a concurrent # call from another thread to get the wwpns. self.instance.refresh() vios_wraps = self.stg_ftsk.feed resp_wwpns = [] # If this is the first time to query the WWPNs for the instance, we # need to generate a set of valid WWPNs. Loop through the configured # FC fabrics and determine if these are new, part of a migration, or # were already configured. for fabric in self._fabric_names(): fc_state = self._get_fabric_state(fabric) LOG.info("NPIV wwpns fabric state=%(st)s.", {'st': fc_state}, instance=self.instance) if self._is_initial_wwpn(fc_state, fabric): # Get a set of WWPNs that are globally unique from the system. v_wwpns = pvm_vfcm.build_wwpn_pair( self.adapter, self.host_uuid, pair_count=self._ports_per_fabric()) # Derive the virtual to physical port mapping port_maps = pvm_vfcm.derive_npiv_map( vios_wraps, self._fabric_ports(fabric), v_wwpns) # the fabric is mapped to the physical port) and the fabric # state. self._set_fabric_meta(fabric, port_maps) self._set_fabric_state(fabric, FS_UNMAPPED) self.instance.save() elif self._is_migration_wwpn(fc_state): # The migration process requires the 'second' wwpn from the # fabric to be used. port_maps = self._configure_wwpns_for_migration(fabric) else: # This specific fabric had been previously set. Just pull # from the meta (as it is likely already mapped to the # instance) port_maps = self._get_fabric_meta(fabric) # Every loop through, we reverse the vios wrappers. This is # done so that if Fabric A only has 1 port, it goes on the # first VIOS. Then Fabric B would put its port on a different # VIOS. This servers as a form of multi pathing (so that your # paths are not restricted to a single VIOS). vios_wraps.reverse() # Port map is set by either conditional, but may be set to None. # If not None, then add the WWPNs to the response. if port_maps is not None: for mapping in port_maps: # Only add the first WWPN. That is the one that will be # logged into the fabric. resp_wwpns.append(mapping[1].split()[0]) # The return object needs to be a list for the volume connector. return resp_wwpns
def wwpns(self): """Builds the WWPNs of the adapters that will connect the ports.""" # Refresh the instance. It could have been updated by a concurrent # call from another thread to get the wwpns. self.instance.refresh() vios_wraps = self.stg_ftsk.feed resp_wwpns = [] # If this is the first time to query the WWPNs for the instance, we # need to generate a set of valid WWPNs. Loop through the configured # FC fabrics and determine if these are new, part of a migration, or # were already configured. for fabric in self._fabric_names(): fc_state = self._get_fabric_state(fabric) LOG.info(_LI("NPIV wwpns fabric state=%(st)s for " "instance %(inst)s") % {'st': fc_state, 'inst': self.instance.name}) if self._is_initial_wwpn(fc_state, fabric): # Get a set of WWPNs that are globally unique from the system. v_wwpns = pvm_vfcm.build_wwpn_pair( self.adapter, self.host_uuid, pair_count=self._ports_per_fabric()) # Derive the virtual to physical port mapping port_maps = pvm_vfcm.derive_npiv_map( vios_wraps, self._fabric_ports(fabric), v_wwpns) # the fabric is mapped to the physical port) and the fabric # state. self._set_fabric_meta(fabric, port_maps) self._set_fabric_state(fabric, FS_UNMAPPED) self.instance.save() elif self._is_migration_wwpn(fc_state): # The migration process requires the 'second' wwpn from the # fabric to be used. port_maps = self._configure_wwpns_for_migration(fabric) else: # This specific fabric had been previously set. Just pull # from the meta (as it is likely already mapped to the # instance) port_maps = self._get_fabric_meta(fabric) # Every loop through, we reverse the vios wrappers. This is # done so that if Fabric A only has 1 port, it goes on the # first VIOS. Then Fabric B would put its port on a different # VIOS. This servers as a form of multi pathing (so that your # paths are not restricted to a single VIOS). vios_wraps.reverse() # Port map is set by either conditional, but may be set to None. # If not None, then add the WWPNs to the response. if port_maps is not None: for mapping in port_maps: # Only add the first WWPN. That is the one that will be # logged into the fabric. resp_wwpns.append(mapping[1].split()[0]) # The return object needs to be a list for the volume connector. return resp_wwpns
def test_build_wwpn_pair(self, mock_job): mock_adpt = mock.MagicMock() mock_adpt.read.return_value = mock.Mock() # Mock out the job response job_w = mock.MagicMock() mock_job.wrap.return_value = job_w job_w.get_job_results_as_dict.return_value = {'wwpnList': 'a,b,c,d,e,f,g,h'} # Invoke and validate resp = vfc_mapper.build_wwpn_pair(mock_adpt, 'host_uuid', pair_count=4) self.assertEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], resp) # Make sure that the job was built properly mock_adpt.read.assert_called_once_with( 'ManagedSystem', root_id='host_uuid', suffix_type=c.SUFFIX_TYPE_DO, suffix_parm=vfc_mapper._GET_NEXT_WWPNS) job_w.create_job_parameter.assert_called_once_with( 'numberPairsRequested', '4')