def test_basic(): a = IQN('iqn.2001-04.com.example:storage:diskarrays-sn-a8675309') assert hash(a) == hash('iqn.2001-04.com.example:storage:diskarrays-sn-a8675309') assert a == a assert a == 'iqn.2001-04.com.example:storage:diskarrays-sn-a8675309' assert a != 'lol' assert a.get_date() == '2001-04' assert a.get_naming_authority() == 'com.example' assert a.get_extra() == 'storage:diskarrays-sn-a8675309' assert a.get_extra_fields() == ('storage', 'diskarrays-sn-a8675309')
def get_system_serial_from_iqn(iqn_str): from infi.dtypes.iqn import IQN, InvalidIQN try: last_iqn_field = IQN(iqn_str).get_extra_fields()[-1] except InvalidIQN: raise InvalidInfiniboxConnectivity("Invalid IQN {}".format(iqn_str)) if last_iqn_field.startswith("infinibox-sn-"): try: return int(last_iqn_field.split("-")[-2]) except ValueError: raise InvalidInfiniboxConnectivity("Invalid InfiniBox IQN {}".format(iqn_str)) raise InvalidInfiniboxConnectivity("Could not get InfiniBox serial from IQN {}".format(iqn_str))
def _get_path_lun_iscsi(self): from infi.storagemodel.unix.utils import execute_command from infi.dtypes.iqn import IQN import re process = execute_command(['iscsiadm', 'list', 'target', '-S']) output = process.get_stdout().splitlines() for line_number, line in enumerate(output): if re.search(r'Target: ', line): result_iqn = line.split()[1] _ = IQN(result_iqn) # make sure iqn is valid if result_iqn != self.target_iqn: continue for indent_line in range(line_number + 1, len(output)): if re.search(r'TPGT:', output[indent_line]): uid = output[indent_line].split()[1] if uid != self.iscsi_session_uid: break if re.search(r'LUN:', output[indent_line]): lun = output[indent_line].split()[1] if re.search('OS Device Name', output[indent_line]): device_name = output[indent_line].split()[3] if device_name == self.mpath_dev_path: return int(lun) elif "array" in self.mpath_dev_path: if "array" in device_name or "Not" in device_name: msg = "correlating device {} <-> {}, both should be lun 0".format( output[indent_line], self.mpath_dev_path) logger.debug(msg) return 0 else: continue if re.search(r'Target: ', output[indent_line]): break # We reached the next target no point searching forward
def _parse_availble_sessions(self): import re availble_sessions = [] cmd = ['iscsiadm', 'list', 'target', '-v'] process = self._execute_assert_n_log(cmd) output = process.get_stdout().splitlines() logger.debug([line.strip() for line in output]) source_ip_regex = re.compile( 'IP address \(Local\): ' r'(?P<src_ip>\d+\.\d+\.\d+\.\d+)\:(?P<src_port>\d+)') target_ip_regex = re.compile( 'IP address \(Peer\): ' r'(?P<dst_ip>\d+\.\d+\.\d+\.\d+)\:(?P<dst_port>\d+)') for line_number, line in enumerate(output): if 'Target: ' in line: iqn = line.split()[1] _ = IQN(iqn) # make sure iqn is valid for ident_line in range(line_number, len(output)): if 'TPGT: ' in output[ident_line]: uid = output[ident_line].split()[1] if source_ip_regex.search(output[ident_line]): session = source_ip_regex.search( output[ident_line]).groupdict() if target_ip_regex.search(output[ident_line]): session.update( target_ip_regex.search( output[ident_line]).groupdict()) session['iqn'] = iqn session['uid'] = uid availble_sessions.append(session) break if re.search('Login Parameters', output[ident_line]): # max search - no point searching after here break return availble_sessions
def _get_target_uid_and_iqn(self): '''returns iscsi target iqn and session uid''' from infi.dtypes.iqn import IQN iqn = self.target_port_name.split(',')[1] _ = IQN(iqn) uid = self.target_port_name.split(',')[2] return iqn, uid
def get_source_iqn(self): from .iscsi_exceptions import NotReadyException client = WmiClient('root\\wmi') query = list( client.execute_query('SELECT * FROM MSIscsiInitiator_MethodClass')) if not query: raise NotReadyException("Could not query iSCSI initiator from WMI") iqn = query[0].Properties_.Item("ISCSINodeName").Value return IQN(iqn)
def set_source_iqn(self, iqn): '''receives a string, validates it's an iqn then set it to the host NOTE: this restart the iscsi service and may fail active sessions ! in Solaris, this doesn't save a copy of the old IQN ''' _ = IQN(iqn) # checks iqn is valid old_iqn = self.get_source_iqn() # check file exist and valid execute_assert_success( ['iscsiadm', 'modify', 'initiator-node', '-N', iqn]) logger.info("iqn was replaced from {} to {}".format(old_iqn, iqn))
def reset_source_iqn(self): '''use in case iqn is invalid and regeneration of it is required''' process = self._execute_assert_success([GENERATE_COMMAND]) iqn = process.get_stdout().strip() _ = IQN(iqn) # validating new IQN logger.info("Regeneration of iqn was initiated, old file {}".format( ISCSI_INITIATOR_IQN_FILE) + "had this data in it {!r}, new iqn is:{}".format( self._get_old_iqn(), iqn)) self.set_source_iqn(iqn)
def set_source_iqn(self, iqn): '''receives a string, validates it's an iqn then set it to the host NOTE: this restart the iscsi service and may fail active sessions ! ''' IQN(iqn) # checks iqn is valid logger.info("Old IQN was:{}".format(self._get_old_iqn())) replacement_strig = 'InitiatorName=' + iqn with open(ISCSI_INITIATOR_IQN_FILE, 'w') as fd: fd.write(replacement_strig + "\n") logger.info("iqn was replaced to {}".format(iqn)) self._reload_iscsid_service()
def get_source_iqn(self): '''return infi.dtypes.iqn type iqn if iscsi initiator file exists ''' from .iscsi_exceptions import NotReadyException import re from os.path import isfile if not isfile(ISCSI_INITIATOR_IQN_FILE): raise NotReadyException("iSCSI initiator IQN file not found") with open(ISCSI_INITIATOR_IQN_FILE, 'r') as fd: data = self._remove_comments(fd.readlines()) assert len(data) == 1, "something isn't right with {}".format( ISCSI_INITIATOR_IQN_FILE) raw_iqn = re.split('InitiatorName=', data[0]) return IQN(raw_iqn[1].strip())
def get_source_iqn(self): '''return infi.dtypes.iqn type iqn if iscsi initiator file exists ''' import re process = self._execute_assert_n_log( ['iscsiadm', 'list', 'initiator-node']) iqn_line = process.get_stdout().splitlines()[0] if re.search(r'Initiator node name', iqn_line): iqn = iqn_line.split('Initiator node name: ')[1] return IQN(iqn) # Validate iqn is legal else: raise RuntimeError( "Couldn't find IQN from iscsiadm output, got {!r}".format( process.get_stdout()))
def _return_target(self, ip_address, port): endpoints = [] iqn = None sessions = self._get_connectivity_using_wmi() for session in sessions: if session['dst_ip'] == ip_address: iqn = IQN(session['iqn']) if iqn is None: raise RuntimeError( "iqn is empty, it means that the discovery address {} didn't returned from the target" .format(ip_address)) for session in sessions: if session['iqn'] == iqn: endpoints.append( base.Endpoint(session['dst_ip'], session['dst_port'])) return base.Target(endpoints, base.Endpoint(ip_address, port), iqn)
def _parse_discovery_address(self, iqn): '''get an iqn of discovered target and return the discovery ip address ''' # TODO: support multiple discovery addresses import re discovery_addresses = [] _ = IQN(iqn) # make sure it's valid iqn cmd = ['iscsiadm', 'list', 'discovery-address'] process = self._execute_assert_n_log(cmd) regex = re.compile('Discovery Address: ' r'(?P<ip>\d+\.\d+\.\d+\.\d+)\:(?P<port>\d+)') for line in process.get_stdout().splitlines(): discovery_addresses.append(regex.search(line).groupdict()['ip']) for path in self._parse_discovered_targets(): if path['iqn'] == iqn: if path['dst_ip'] in discovery_addresses: return (path['dst_ip'], path['dst_port'])
def set_source_iqn(self, iqn): '''receive an iqn as a string, verify it's valid and set it. returns iqn type of the new IQN or None if fails ''' logger.info( "iqn before the change is {!r} going to change to {!r}".format( self.get_source_iqn(), iqn)) IQN(iqn) # raise if iqn doesn't exist client = WmiClient('root\\wmi') query = list( client.execute_query( "SELECT * FROM MSIscsiInitiator_MethodClass"))[0] initiator_name = query.Methods_.Item("SetIscsiInitiatorNodeName") parameters = initiator_name.InParameters.SpawnInstance_() parameters.Properties_.Item("InitiatorNodeName").Value = iqn query.ExecMethod_('SetIscsiInitiatorNodeName', parameters) logger.info("iqn is now {!r}".format(self.get_source_iqn())) return self.get_source_iqn()
def _parse_discovery_address(self, iqn): '''get an iqn of discovered target and return the discovery ip address ''' import os import re import glob regex = re.compile('node.discovery_address = ' r'(?P<ip>\d+\.\d+\.\d+\.\d+)') _ = IQN(iqn) # make sure it's valid iqn for filepath in glob.glob( os.path.join( ISCSI_CONNECTION_CONFIG, iqn, '*', # target address 'default')): try: with open(filepath, 'r') as fd: for line in fd: if re.match(regex, line.strip()): return regex.search(line.strip()).groupdict()['ip'] except (OSError, IOError): continue
def _parse_discovery_endpoint(self, iqn): '''get an iqn of discovered target and return the discovery ip address ''' import re IQN(iqn) # make sure it's a valid iqn for end_point in os.listdir(os.path.join(ISCSI_CONNECTION_CONFIG, iqn)): filepath = os.path.join(ISCSI_CONNECTION_CONFIG, iqn, end_point) # HPT-2193 filepath could be a file with the node info, or a dir that contains a file "default" which # has the information if os.path.isdir(filepath): filepath = os.path.join(filepath, 'default') if not os.path.isfile(filepath): continue try: with open(filepath, 'r') as fd: content = fd.read() except (OSError, IOError): continue ip = re.search("node.discovery_address\s*=\s*(\d+\.\d+\.\d+\.\d+)", content) port = re.search("node.discovery_port\s*=\s*(\d+)", content) if ip is not None and port is not None: return base.Endpoint(ip.group(1), int(port.group(1)))
def set_source_iqn(self, iqn): _ = IQN(iqn) # checks iqn is valid self._get_host_storage_system().UpdateInternetScsiName( self._get_source_iqn(), iqn)
def test_rfc_examples(): a = IQN('iqn.2001-04.com.example') assert a.get_date() == '2001-04' assert a.get_naming_authority() == 'com.example' assert a.get_extra() == '' assert a.get_extra_fields() == ()
def get_source_iqn(self): return [ IQN(iscsi_adapter.iScsiName) for iscsi_adapter in self._get_all_iscsi_host_bus_adapters() ]
def _get_source_iqn(self, adapter=None): # this get_source_iqn returns a single iqn for the currently used hba # the external get_source_iqn returns all iqns (from all adapters), in order for 'register' to register all # available iqns on host iscsi_adapter = self._get_iscsi_host_bus_adapter(adapter) return IQN(iscsi_adapter.iScsiName)
def get_target_iqn(self): if isinstance(self._target_iqn, six.string_types): return IQN(self._target_iqn) return self._target_iqn