def get_fc_hba_descriptors(vmhbaname, executor): exec_ = command.get_exec_fn(executor) vmkmgmt_keyval_cls = vmkmgmt_keyval.find(executor) vmkmgmt_keyval_impl = vmkmgmt_keyval_cls() instances = exec_(vmkmgmt_keyval_impl.dumpInstances) fn = comp(methodcaller('startswith', 'qlnativefc'), methodcaller('lower')) for instance in ifilter(fn, instances): key_descriptors = exec_(vmkmgmt_keyval_impl.instance(instance).list) for descriptor in key_descriptors: if vmhbaname in descriptor.value: return _parse(vmhbaname, descriptor)
def groupby_unique_key(lines, separator=':'): '''Groupes key value output to the list of dictionaries. Decides whether current dictionary is completed by checking if current key was already added to the dictionary. The line is skipped if it does not contain separator substring @param lines: sequence of strings to use as input data to group @type lines: seq[basestring] @param separator: separator to be used while identifying key-value pairs @type separator: basestring @return: sequence of dictionaries @rtype: seq[dict] ''' grouped = [] if lines: sep_pattern = re.compile('\s*%s\s*' % separator) split_by_sep = fptools.comp(sep_pattern.split, methodcaller('strip')) lines = ifilter(identity, lines) _kwargs = {} for keyval in imap(split_by_sep, lines): if len(keyval) == 2: key, value = keyval if key in _kwargs: grouped.append(_kwargs) _kwargs = {} _kwargs[key] = value if _kwargs: grouped.append(_kwargs) return tuple(grouped)
def is_applicable(fcstat, bin, executor): '''Returns bool value indicating whether current command is applicable for target destination @param bin: path to binary @type bin: basestring @param executor: a command executor instance @type executor: command.Executor @return: True if command is applicable for target destination, False otherwise @rtype: bool @raise command.ExecuteException: on `fcstat` command execution failure or the command returns None result ''' handlers = (command.UnixBaseCmd.DEFAULT_HANDLERS + ( command.cmdlet.raiseWhenOutputIsNone, attrgetter('output'), methodcaller('strip'), )) handler = fcstat.compose_handler(handlers) result = executor.process(fcstat(bin=bin, handler=handler)) result = result.handler(result) return result == 'usage: fcstat [-z[-d] | -d | -e[-d] ] Device_name'
def is_applicable(lsdev, bin, executor): '''Returns bool value indicating whether current command is applicable for target destination @param bin: path to binary @type bin: basestring @param executor: a command executor instance @type executor: command.Executor @return: True if command is applicable for target destination, False otherwise @rtype: bool @raise command.ExecuteException: on `lsdev --help` command timeout or None output returned ''' expected_options = ('lsdev [-type DeviceType ...]', '[-field FieldName ...]', 'lsdev -vpd', '-dev ') def are_all_options_present(output): return all(option in output for option in expected_options) handlers = (command.UnixBaseCmd.DEFAULT_HANDLERS + ( command.cmdlet.raiseWhenOutputIsNone, attrgetter('output'), methodcaller('strip'), are_all_options_present )) handler = lsdev.compose_handler(handlers) exec_ = executor(useCache=1).process result = exec_(lsdev(bin, options=['--help', ], handler=handler)) return result.handler(result)
def _parse_list(text): text = text[len('Listing keys:'):].strip() p = re.compile('Name:(.+?)Type:(.+?)value:', re.DOTALL) result = [] for chunk in _paginate(p.split(text)[1:], 3): result.append(KeyDescriptor(*map(methodcaller('strip'), chunk))) return tuple(result)
def parse_f_option_row(row): '''parses `ioscan -fnC <class>` command result particular row returning descriptor object @param row: separated by witespace module's class, instance number, hardware path, driver, software state, hardware type, and a brief description. @type row: str or unicode @return: descriptor of `ioscan -fnC <class>` command output or None on parse failure @rtype: fOptionDescriptor @tito: { 'fc 0 40/0/0/2/0/0/0 fcd CLAIMED INTERFACE HP AH401A 8Gb Dual Port PCIe Fibre Channel Adapter (FC Port 1)': fOptionDescriptor('fc', '0', '40/0/0/2/0/0/0', 'fcd', 'CLAIMED', 'INTERFACE', 'HP AH401A 8Gb Dual Port PCIe Fibre Channel Adapter (FC Port 1)', None) } ''' chunks = map(fptools.methodcaller('strip'), row.split()) if len(chunks) >= 7: details_chunks = chunks[:6] description_chunks = chunks[6:] description = ' '.join(description_chunks) (clazz, instance_number, hw_path, driver, sw_state, hw_type) = details_chunks return fOptionDescriptor(clazz=clazz, instance_number=instance_number, hw_path=hw_path, driver=driver, sw_state=sw_state, hw_type=hw_type, description=description, device_filename=None)
def is_applicable(fcinfo, bin, executor): '''Returns bool value indicating whether current command is applicable for target destination @param bin: path to binary @type bin: basestring @param executor: a command executor instance @type executor: command.Executor @return: True if command is applicable for target destination, False otherwise @rtype: bool ''' handlers = (command.UnixBaseCmd.DEFAULT_HANDLERS + ( command.cmdlet.raiseWhenOutputIsEmpty, attrgetter('output'), methodcaller('strip'), )) handler = fcinfo.compose_handler(handlers) exec_ = Sfn(executor(useCache=1).process) result = exec_(fcinfo(bin, options=[ '-?', ], handler=handler)) if result: result = result.handler(result) return 'fcinfo hba-port' in result and 'fcinfo remote-port' in result
def is_applicable(lsdev, bin, executor): '''Returns bool value indicating whether current command is applicable for target destination @param bin: path to binary @type bin: basestring @param executor: a command executor instance @type executor: command.Executor @return: True if command is applicable for target destination, False otherwise @rtype: bool ''' expected_output = 'usage: lscfg [-vps] [-l Name ]' raise_on_invalid_return_code = partial(raise_on_return_code_not_in_range, codes=(1, )) handlers = (command.UnixBaseCmd.DEFAULT_HANDLERS + (raise_on_invalid_return_code, command.cmdlet.raiseWhenOutputIsNone, attrgetter('output'), methodcaller('strip'), )) handler = lsdev.compose_handler(handlers) exec_ = Sfn(executor(useCache=1).process) result = exec_(lsdev(bin, options=['usage', ], handler=handler)) if result: result = result.handler(result) return result == expected_output
def is_applicable(fcinfo, bin, executor): '''Returns bool value indicating whether current command is applicable for target destination @param bin: path to binary @type bin: basestring @param executor: a command executor instance @type executor: command.Executor @return: True if command is applicable for target destination, False otherwise @rtype: bool ''' handlers = (command.UnixBaseCmd.DEFAULT_HANDLERS + ( command.cmdlet.raiseWhenOutputIsEmpty, attrgetter('output'), methodcaller('strip'), )) handler = fcinfo.compose_handler(handlers) exec_ = Sfn(executor(useCache=1).process) result = exec_(fcinfo(bin, options=['-?', ], handler=handler)) if result: result = result.handler(result) return 'fcinfo hba-port' in result and 'fcinfo remote-port' in result
def is_applicable(lsdev, bin, executor): '''Returns bool value indicating whether current command is applicable for target destination @param bin: path to binary @type bin: basestring @param executor: a command executor instance @type executor: command.Executor @return: True if command is applicable for target destination, False otherwise @rtype: bool @raise command.ExecuteException: on `lsdev --help` command timeout or None output returned ''' expected_options = ('lsdev [-type DeviceType ...]', '[-field FieldName ...]', 'lsdev -vpd', '-dev ') def are_all_options_present(output): return all(option in output for option in expected_options) handlers = ( command.UnixBaseCmd.DEFAULT_HANDLERS + (command.cmdlet.raiseWhenOutputIsNone, attrgetter('output'), methodcaller('strip'), are_all_options_present)) handler = lsdev.compose_handler(handlers) exec_ = executor(useCache=1).process result = exec_(lsdev(bin, options=[ '--help', ], handler=handler)) return result.handler(result)
def _parse(vmhbaname, descriptor): m = re.search('.+Fibre Channel Host Adapter for (.+?):.*' 'Firmware version (.+?), Driver version(.+?)' 'Host Device Name %s.+Serial#(.+?)MSI-X' % vmhbaname, descriptor.value, re.DOTALL) if m: return FcHbaDescriptor(*imap(methodcaller('strip'), m.groups()))
def dumpInstances(self): handlers = (Cmd.DEFAULT_HANDLERS + ( methodcaller('splitlines'), _parse_dumpinstances, )) handler = Cmd.compose_handler(handlers) return self._with_option("-d", handler=handler)
class Cmd(_BaseCmd): '''A wrapper for `ioscan` command providing proper handling for each relevant option Note: the handler will throw command.ExecuteException if * the command returns non zero return code * the output is empty ''' DEFAULT_HANDLERS = (_BaseCmd.DEFAULT_HANDLERS + ( command.cmdlet.raiseOnNonZeroReturnCode, command.cmdlet.raiseWhenOutputIsNone, command.cmdlet.stripOutput, fptools.methodcaller('splitlines'), command.parser.clean_sudo_last_login_information_in_en, )) def __init__(self, cmdline='ioscan', f_option_handler=None, handler=None): ''' @param cmdline: cmdline for current command @type cmdline: str or unicode @param f_option_handler: link to -f/-F option handler @type f_option_handler: FOptionHandlerWrapper @param handler: handler to use for current command @type handler: callable[command.Result] -> ?. The default handler returns `ioscan` command output splitted by lines ''' command.BaseCmd.__init__(self, cmdline, handler) self.f_option_handler = f_option_handler def f(self): '''Creates command with `ioscan -f` cmdline and handler returning fOptionDescriptor objects''' f_option_handler = FOptionHandlerWrapper(parse_f_option_row) handler = comp(f_option_handler, skip_f_option_header, self.handler) return Cmd('%s -f' % self.cmdline, f_option_handler=f_option_handler, handler=handler) def n(self): '''Creates command appending "-n" option to the existing command line''' if not self.f_option_handler: raise ValueError( '"-n" option must be used with either the -f or the -F option.' ) self.f_option_handler.with_n_option = True cmd = Cmd('%s -n' % self.cmdline, f_option_handler=self.f_option_handler, handler=self.handler) return cmd def C(self, cls): '''Creates command appending "-C <class>" option to the existing command line @param cls: class to list devices for @type cls: str or unicode @return: new command with "-C <class>" appended @rtype: Cmd ''' return Cmd('%s -C %s' % (self.cmdline, cls), f_option_handler=self.f_option_handler, handler=self.handler)
def _parse(descriptor): m = re.search('.+Emulex.+?(\d+\.\d+\.\d+\.\d+).+' '(Emulex .+?)on PCI bus.+FW Version:(.+)' 'HW Version.+SerialNum:(.+)Vendor Id.+', descriptor.value, re.DOTALL) if m: driverversion, model, firmwareversion, serialnumber = imap(methodcaller('strip'), m.groups()) return FcHbaDescriptor(model, firmwareversion, driverversion, serialnumber)
def _parse(descriptor): m = re.search( '.+Emulex.+?(\d+\.\d+\.\d+\.\d+).+' '(Emulex .+?)on PCI bus.+FW Version:(.+)' 'HW Version.+SerialNum:(.+)Vendor Id.+', descriptor.value, re.DOTALL) if m: driverversion, model, firmwareversion, serialnumber = imap( methodcaller('strip'), m.groups()) return FcHbaDescriptor(model, firmwareversion, driverversion, serialnumber)
class Cmd(command.BaseCmd): '''A wrapper for `fcmsutil` command providing proper handling for each relevant option Note: the handler will throw command.ExecuteException if * the command returns non zero return code * the output is empty ''' DEFAULT_HANDLERS = (command.BaseCmd.DEFAULT_HANDLERS + ( command.cmdlet.raiseOnNonZeroReturnCode, command.cmdlet.raiseWhenOutputIsNone, command.cmdlet.stripOutput, fptools.methodcaller('splitlines'), command.parser.clean_sudo_last_login_information_in_en, )) def __init__(self, cmdline=None, device_filename=None, bin_path='fcmsutil', handler=None): ''' @param cmdline: commandline to use for this command @type cmdline: str or unicode @param device_filename: the Fibre Channel device special file associated with the Fibre Channel HBA port. The device file has the format /dev/FC_driverX, where X is the instance number of the Fibre Channel HBA port, as reported by the ioscan output @type device_filename: str or unicode @param bin_path: path to fcmsutil binary @type bin_path: str ot unicode @param handler: handler to use for current command @type handler: callable[command.Result] -> ?. The default handler returns FcmsutilDescriptor object ''' if not cmdline and not device_filename: raise ValueError( 'Neither cmdline nor device_filename are provided') cmdline = cmdline or ' '.join((bin_path, device_filename)) handler = handler or comp(parse_fcmsutil, self.get_default_handler()) command.BaseCmd.__init__(self, cmdline, handler=handler) def vpd(self): '''Create command with `fcmsutil <device_filename> vpd` cmdline and handler returning FcmsutilVpdOptionDescriptor object''' handler = comp(parse_vpd_option, self.get_default_handler()) return Cmd(cmdline='%s vpd' % self.cmdline, handler=handler) def remote(self, remote_n_port_id='all'): '''Create command with `fcmsutil <device_filename> remote <remote_n_port_id>` cmdline and handler returning FcmsutilRemoteOptionDescriptor colelction''' parse = parse_remote_option if remote_n_port_id == 'all': parse = parse_remote_all_option handler = comp(parse, self.get_default_handler()) return Cmd(cmdline='%s get remote %s' % (self.cmdline, remote_n_port_id), handler=handler)
def get_driver_version(self, driverid, exec_): '''Discovers driver version string by provided device id with `lslpp` command @param driverid: driver id string returned either by `fcstat fcx`, `lsdev -vpd -dev fcx` or `lscfg -vpl fcx` commands @type driverid: str @param exec_: callable to execute commands and produce result @type exec_: callable[command.Cmd]->object @return: driver version string @rtype: str ''' cmdline = 'lslpp -l "*%s.rte"' % driverid handlers = (command.UnixBaseCmd.DEFAULT_HANDLERS + (command.raise_on_non_zero_return_code, command.raise_when_output_is_empty, attrgetter('output'), methodcaller('strip'), methodcaller('splitlines'), _parse_driver_version)) handler = command.UnixBaseCmd.compose_handler(handlers) c = command.UnixBaseCmd(cmdline, handler=handler) return exec_(c)
def _parse_embedded_object(type_, object_value): m = re.match('instance of %s.+?{(.+)};' % type_, object_value.strip(), re.DOTALL) key_value_pairs = m.group(1).strip() sep_pattern = re.compile('\s*=\s*') split_by_sep = fptools.comp(sep_pattern.split, methodcaller('strip')) lines = ifilter(identity, key_value_pairs.splitlines()) res = {} for key, value in imap(split_by_sep, lines): #skip semicolon at the end value = value[:-1] res[key] = value return res
def __parse_db2cli_ini(self, content): """ :param content: ini file content :type content: str or unicode :return: hostname, port, database :rtype: str, int, str """ if content: lines = ifilter(None, imap(methodcaller('strip'), content.splitlines())) config = iniparser.getInivars(lines) items = dict(config.items(self._name)) if items and items.get("dbalias") is None: return items.get("hostname"), items.get("port"), items.get("database")
def parse_remote_all_option(lines): '''parses `fcmsutil <device_filename> remote all` command output returning the descriptor object @param lines: output of `fcmsutil <device_filename> remote all` command splited by lines @type lines: list of str or unicode @return: descriptor of fcmsutil command output or None on parse failure @rtype: list[RemoteOptionDescriptor] ''' result = [] if len(lines) > 1: separator = '=' sep_pattern = re.compile('\s*%s\s*' % separator) split_by_sep = fptools.comp(sep_pattern.split, methodcaller('strip')) lines = ifilter(identity, lines) grouped = [] _kwargs = {} for keyval in imap(split_by_sep, lines): if len(keyval) == 2: key, value = keyval if key in _kwargs: grouped.append(_kwargs) _kwargs = {} _kwargs[key] = value grouped.append(_kwargs) for item in grouped: target_n_port_id = item.get('Target N_Port_id is') target_loop_id = item.get('Target Loop_id is') target_state = item.get('Target state') symbolic_port_name = item.get('Symbolic Port Name') symbolic_node_name = item.get('Symbolic Node Name') port_type = item.get('Port Type') fcp_2_support = item.get('FCP-2 Support') target_port_wwn = item.get('Target Port World Wide Name') target_node_wwn = item.get('Target Node World Wide Name') result.append(RemoteOptionDescriptor(target_n_port_id, target_loop_id, target_state, symbolic_port_name, symbolic_node_name, port_type, fcp_2_support, target_port_wwn, target_node_wwn)) return tuple(result)
def get_driver_version(self, driverid, exec_): '''Discovers driver version string by provided device id with `lslpp` command @param driverid: driver id string returned either by `fcstat fcx`, `lsdev -vpd -dev fcx` or `lscfg -vpl fcx` commands @type driverid: str @param exec_: callable to execute commands and produce result @type exec_: callable[command.Cmd]->object @return: driver version string @rtype: str ''' cmdline = 'lslpp -l "*%s.rte"' % driverid handlers = (command.UnixBaseCmd.DEFAULT_HANDLERS + (command.raise_on_non_zero_return_code, command.raise_when_output_is_empty, attrgetter('output'), methodcaller('strip'), methodcaller('splitlines'), _parse_driver_version )) handler = command.UnixBaseCmd.compose_handler(handlers) c = command.UnixBaseCmd(cmdline, handler=handler) return exec_(c)
def list_fc_adapter_names(self, lsdev, exec_): '''Lists all available fc adapater names using provided lsdev wrapper implementation @param lsdev: lsdev command implementation @type lsdev: lsdev_aix.Cmd @param exec_: callable to execute commands and produce result @type exec_: callable[command.Cmd]->object @return: list of fc adapter names @rtype: list[str] ''' lsdev = lsdev() cmd = lsdev.list_device_names(lsdev.classes.adapter) devices = exec_(cmd) fn = fptools.methodcaller('startswith', 'fcs') return filter(fn, devices)
def __parse_db2cli_ini(self, content): """ :param content: ini file content :type content: str or unicode :return: hostname, port, database :rtype: str, int, str """ if content: lines = ifilter(None, imap(methodcaller('strip'), content.splitlines())) config = iniparser.getInivars(lines) items = dict(config.items(self._name)) if items and items.get("dbalias") is None: return items.get("hostname"), items.get("port"), items.get( "database")
def parse_storage_san_fc_list(cls, text): lines = text.splitlines() separator = '\:' sep_pattern = re.compile('\s*%s\s*' % separator) lines = ifilter(identity, lines) grouped = [] key_value = {} for keyvalue in imap(methodcaller('strip'), lines): key, value = sep_pattern.split(keyvalue, maxsplit=1) if key in key_value: grouped.append(key_value) key_value = {} key_value[key] = value grouped.append(key_value) return tuple(grouped)
class Cmd(lsdev_aix.Cmd): ''' Command class for AIX `lsdev` executable extending command.BaseCmd.DEFAULT_HANDLERS static attribute with additional handlers specific to `lsdev` command, defining r, C and c public methods. The class overrides parent is_applicable and lis_device_names methods providing relevant implementations. Class also defines BIN static attribute to hold path to `lsdev` binary ''' DEFAULT_HANDLERS = (command.UnixBaseCmd.DEFAULT_HANDLERS + (command.cmdlet.raiseOnNonZeroReturnCode, command.cmdlet.raiseWhenOutputIsNone, command.cmdlet.stripOutput, fptools.methodcaller('splitlines'), command.parser.clean_sudo_last_login_information_in_en, )) def list_device_names(self, device_class): return self.C.c(device_class).r('name') def r(self, fieldname): return self._with_option("-r %s" % fieldname) @property def C(self): return self._with_option("-C") def c(self, device_class): return self._with_option("-c %s" % device_class) @classmethod def is_applicable(lsdev, bin, executor): '''Returns bool value indicating whether current command is applicable for target destination @param bin: path to binary @type bin: basestring @param executor: a command executor instance @type executor: command.Executor @return: True if command is applicable for target destination, False otherwise @rtype: bool ''' return not shell_interpreter.isRestrictedShell(executor.shell)
def parse_vpd_option(lines): '''parses `fcmsutil <device_filename> vpd` command output returning the descriptor object @param lines: output of `fcmsutil <device_filename> vpd` command splited by lines @type lines: list of str or unicode @return: descriptor of fcmsutil command output or None on parse failure @rtype: FcmsutilVpdOptionDescriptor ''' lines = lines[3:] separator = '\:' sep_pattern = re.compile('\s*%s\s*' % separator) split_by_sep = fptools.comp(second, sep_pattern.split, fptools.methodcaller('strip')) lines = ifilter(identity, lines) values = map(split_by_sep, lines) if len(values) == 13: return FcmsutilVpdOptionDescriptor(*values)
def parse_remote_all_option(lines): '''parses `fcmsutil <device_filename> remote all` command output returning the descriptor object @param lines: output of `fcmsutil <device_filename> remote all` command splited by lines @type lines: list of str or unicode @return: descriptor of fcmsutil command output or None on parse failure @rtype: list[RemoteOptionDescriptor] ''' result = [] if len(lines) > 1: separator = '=' sep_pattern = re.compile('\s*%s\s*' % separator) split_by_sep = fptools.comp(sep_pattern.split, methodcaller('strip')) lines = ifilter(identity, lines) grouped = [] _kwargs = {} for keyval in imap(split_by_sep, lines): if len(keyval) == 2: key, value = keyval if key in _kwargs: grouped.append(_kwargs) _kwargs = {} _kwargs[key] = value grouped.append(_kwargs) for item in grouped: target_n_port_id = item.get('Target N_Port_id is') target_loop_id = item.get('Target Loop_id is') target_state = item.get('Target state') symbolic_port_name = item.get('Symbolic Port Name') symbolic_node_name = item.get('Symbolic Node Name') port_type = item.get('Port Type') fcp_2_support = item.get('FCP-2 Support') target_port_wwn = item.get('Target Port World Wide Name') target_node_wwn = item.get('Target Node World Wide Name') result.append( RemoteOptionDescriptor(target_n_port_id, target_loop_id, target_state, symbolic_port_name, symbolic_node_name, port_type, fcp_2_support, target_port_wwn, target_node_wwn)) return tuple(result)
def list_fchost_remote_ports(list_dir_fullnames_fn, fc_host): '''Returns list of paths of corresponding to fc_host class remote instances @param list_dir_fullnames_fn: callable returning list of child path instances corresponding to passed path. @type list_dir_fullnames_fn: callable[basestring or file_system.Path] -> list[file_system.Path]. The callable may throw command.ExecuteException on list dir names failure @param fc_host: name of fc host instance to list remote ports for @type fc_host: basestring @return: list of pathes of child directories for the target folder @rtype: list[file_system.Path] @raise command.ExecuteException: on list directory failure ''' path = UnixPath('/sys/class/fc_host/%s/device' % fc_host) return filter(methodcaller('startswith', 'rport-'), map(attrgetter('basename'), list_dir_fullnames_fn(path)))
def parse_fcmsutil(lines): '''parses `fcmsutil <device_filename>` command output returning the descriptor object @param lines: output of `fcmsutil <device_filename>` command splited by lines @type lines: list of str or unicode @return: descriptor of fcmsutil command output or None on parse failure @rtype: FcmsutilDescriptor ''' separator = '=' sep_pattern = re.compile('\s*%s\s*' % separator) split_by_sep = fptools.comp(second, sep_pattern.split, fptools.methodcaller('strip')) lines = ifilter(identity, lines) values = map(split_by_sep, lines) topology_index = 7 if len(values) > 7 and not values[topology_index] == 'PRIVATE_LOOP': values.insert(11, None) if len(values) == 26: return FcmsutilDescriptor(*values)
def get_vendor_by_device_id(self, device_id, executor): '''Returns vendor name by device id @param device_id: id of device in form <domain>:<bus>:<slot> @type device_id: basestring @param executor: instance of a command executor @type executor: command.Executor @return: vendor name @rtype: basestring ''' handler = comp(*reversed((command.cmdlet.raiseOnNonZeroReturnCode, command.cmdlet.raiseWhenOutputIsNone, command.cmdlet.stripOutput, fptools.methodcaller('splitlines'), _parse_lspci))) lspci = command.UnixBaseCmd("lspci -v -m -n -s %s" % device_id, handler=handler) result = executor.process(lspci) return vendors.find_name_by_id_in_hex(result.get('vendor'))
class Cmd(command.UnixBaseCmd): ''' Command class for `ls` executable extending command.BaseCmd.DEFAULT_HANDLERS static attribute with additional handlers specific to `ls` command. Class also defines BIN static attribute to hold path to `ls` binary ''' DEFAULT_HANDLERS = (command.UnixBaseCmd.DEFAULT_HANDLERS + ( command.cmdlet.raiseOnNonZeroReturnCode, command.cmdlet.raiseWhenOutputIsNone, command.cmdlet.stripOutput, fptools.methodcaller('splitlines'), command.parser.clean_sudo_last_login_information_in_en, )) BIN = 'ls' def __init__(self, path=None, options=None, handler=None): ''' @param path: file path to get resolve @type path: basestring or file_system.Path @param options: list of ls options @type options: list[str] @param handler: handler to use for current command @type handler: callable[command.Result] -> ?. The default handler returns `ls` command output splitted by lines ''' self.path = path and unicode(path) self.options = options or [] command.UnixBaseCmd.__init__(self, self._build_cmdline(), handler=handler) def _build_cmdline(self): cmdline = self.path and ' '.join((self.BIN, self.path)) or self.BIN return ' '.join([ cmdline, ] + self.options) def _with_option(self, option, handler=None): handler = handler or self.handler options = self.options[:] options.append(option) return Cmd(self.path, options, handler) @property def d(self): '''Returns new command appending '-d' to current commandline @return: new command instance with '-d' option appended @rtype: ls.Cmd ''' return self._with_option('-d') @property def no_color(self): '''Returns command disabling colored output. @return: current command with no color option @rtype: ls.Cmd ''' return self @property def file_per_line(self): '''Returns new command appending '-1' to current commandline to initiate one file per line output format @return: new command instance with '-1' option appended @rtype: ls.Cmd ''' return self._with_option('-1') @classmethod def create(cls, bin): '''Creates new class definition with new BIN attribute value @param bin: path to binary @type bin: basestring @return: new definition of a class with new BIN attribute value @rtype: ls.Cmd ''' class cls_(cls): BIN = bin return cls_ @classmethod def is_applicable(ls, executor): '''Returns bool value indicating whether current command is applicable for target destination @param executor: a command executor instance @type executor: command.Executor @return: True if command is applicable for target destination, False otherwise @rtype: bool ''' raise NotImplementedError('is_applicable')
def _get_keyname(self): return findFirst(methodcaller('startswith', '-k'), self.options)
def get_fc_hbas(self, shell): result = defaultdict(list) executor = command.cmdlet.executeCommand(shell) esxcli = find_esxcli_impl(executor)() esxcli = esxcli.formatter('csv') esxcli_exec = command.get_exec_fn(esxcli, executor) storage = EsxcliStorageNamespace(esxcli) software = EsxcliSoftwareNamespace(esxcli) scsi_path_by_adapter_identifier = fptools.groupby(methodcaller('get', 'AdapterIdentifier'), esxcli_exec(storage.core.path.list())) adapters = esxcli_exec(storage.core.adapter.list()) grouped_adapters = dict((adapter.get('HBAName'), adapter) for adapter in adapters) grouped = defaultdict(list) for descriptor in esxcli_exec(storage.san.fc.list()): grouped[(descriptor.get('Adapter'), descriptor.get('NodeName'))].append(descriptor) get_vendor = Sfn(self.get_vendor) get_fchba_descriptor = Sfn(self._get_fchba_descriptor) for key, descriptors in grouped.iteritems(): try: vmhba, nodewwn = key nodewwn = wwn.parse_from_str(nodewwn) name = vmhba id_ = vmhba adapter_descriptor = grouped_adapters.get(vmhba) driverversion = None vendor = get_vendor(vmhba, executor) model = None fwversion = None serialnum = None if adapter_descriptor: id_ = adapter_descriptor.get('UID') driver = adapter_descriptor.get('Driver') vib_descriptor = esxcli_exec(software.vib.get(vibname=driver)) driverversion = vib_descriptor.get('Version') fchabdescriptor = get_fchba_descriptor(driver, vmhba, executor) if fchabdescriptor: model = fchabdescriptor.model fwversion = fchabdescriptor.firmwareversion serialnum = fchabdescriptor.serialnumber driverversion = fchabdescriptor.driverversion fchba = fc_hba_model.FcHba(id_, name, wwn=nodewwn, vendor=vendor, model=model, serial_number=serialnum, driver_version=driverversion, firmware_version=fwversion) ports = [] for fcdescriptor in descriptors: try: portwwn = fcdescriptor.get('PortName') porttype = fcdescriptor.get('PortType') portwwn = wwn.parse_from_str(portwwn) portid = fcdescriptor.get('PortID') port_speed = _parse_port_speed(fcdescriptor.get('Speed')) portid = Sfn(int)(portid, 16) adapter_identifier = self._compose_adapter_identifier(nodewwn, portwwn) scsi_paths = scsi_path_by_adapter_identifier.get(adapter_identifier) target_fcdescriptors = self._create_target_fchba_details(scsi_paths) ports.append((fc_hba_model.FcPort(portid, portwwn, porttype, None, port_speed), target_fcdescriptors)) except (command.ExecuteException, TypeError, ValueError), ex: logger.debugException('Failed to create fcport data object') result[fchba].extend(ports) except (command.ExecuteException, TypeError, ValueError), ex: logger.debugException('Failed to create fchba data object')
class Cmd(command.UnixBaseCmd): ''' Command class for AIX `lsdev` executable extending command.BaseCmd.DEFAULT_HANDLERS static attribute with additional handlers specific to `lsdev` command, defining list_device_names and is_applicable public methods. Class also defines BIN static attribute to hold path to `lsdev` binary and static classes enum containing all available device class names ''' DEFAULT_HANDLERS = (command.UnixBaseCmd.DEFAULT_HANDLERS + ( command.cmdlet.raiseOnNonZeroReturnCode, command.cmdlet.raiseWhenOutputIsNone, command.cmdlet.stripOutput, fptools.methodcaller('splitlines'), command.parser.clean_sudo_last_login_information_in_en, )) BIN = 'lsdev' class ClassEnum: adapter = 'adapter' classes = ClassEnum() def __init__(self, bin=None, options=None, handler=None): ''' @param bin: file path to get resolve @type bin: basestring or file_system.Path @param options: list of ls options @type options: list[str] @param handler: handler to use for current command @type handler: callable[command.Result] -> ?. The default handler returns `lsdev` command output splitted by lines ''' self.bin = bin and unicode(bin) self.options = options or [] command.UnixBaseCmd.__init__(self, self._build_cmdline(), handler=handler) def _build_cmdline(self): cmdline = self.bin or self.BIN return ' '.join([ cmdline, ] + self.options) def _with_option(self, option, handler=None): handler = handler or self.handler options = self.options[:] options.append(option) return self.__class__(self.bin, options, handler) def list_device_names(self, device_class): '''Returns a command to list available device names for provided class @param device_class: target device class to provide names for @type device_class: basestring @return: list of available device names @rtype:lsdev_aix.Cmd ''' raise NotImplementedError('list_device_names') @classmethod def is_applicable(lsdev, bin, executor): '''Returns bool value indicating whether current command is applicable for target destination @param bin: path to binary @type bin: basestring @param executor: a command executor instance @type executor: command.Executor @return: True if command is applicable for target destination, False otherwise @rtype: bool ''' raise NotImplementedError('is_applicable')
def _parse_dumpinstances(lines): lines = lines[1:] p = re.compile('\:') return map(comp(methodcaller('strip'), second, p.split), lines)
class Cmd(command.UnixBaseCmd): ''' Command class for AIX `lscfg` executable extending command.BaseCmd.DEFAULT_HANDLERS static attribute with additional handlers specific to `lscfg` command, defining is_applicable public methods. Class defines BIN static attribute to hold path to `lscfg` binary and *v *p *l public methods corresponding to same named lscfg options Class also defines BIN static attribute to hold path to `lscfg` binary ''' DEFAULT_HANDLERS = (command.UnixBaseCmd.DEFAULT_HANDLERS + (command.cmdlet.raiseOnNonZeroReturnCode, command.cmdlet.raiseWhenOutputIsNone, command.cmdlet.stripOutput, fptools.methodcaller('splitlines'), )) BIN = 'lscfg' def __init__(self, bin=None, options=None, handler=None): ''' @param bin: file path to get resolve @type bin: basestring or file_system.Path @param options: list of ls options @type options: list[str] @param handler: handler to use for current command @type handler: callable[command.Result] -> ?. The default handler returns `lscfg` command output splitted by lines ''' self.bin = bin and unicode(bin) self.options = options or [] command.UnixBaseCmd.__init__(self, self._build_cmdline(), handler=handler) def _build_cmdline(self): cmdline = self.bin or self.BIN return ' '.join([cmdline, ] + self.options) def _with_option(self, option, handler=None): handler = handler or self.handler options = self.options[:] options.append(option) return self.__class__(self.bin, options, handler) def v(self, handler=None): return self._with_option("-v", handler=handler) def p(self, handler=None): return self._with_option("-p", handler=handler) def l(self, devicename, handler=None): return self._with_option("-l %s" % devicename, handler=handler) @classmethod def is_applicable(lsdev, bin, executor): '''Returns bool value indicating whether current command is applicable for target destination @param bin: path to binary @type bin: basestring @param executor: a command executor instance @type executor: command.Executor @return: True if command is applicable for target destination, False otherwise @rtype: bool ''' expected_output = 'usage: lscfg [-vps] [-l Name ]' raise_on_invalid_return_code = partial(raise_on_return_code_not_in_range, codes=(1, )) handlers = (command.UnixBaseCmd.DEFAULT_HANDLERS + (raise_on_invalid_return_code, command.cmdlet.raiseWhenOutputIsNone, attrgetter('output'), methodcaller('strip'), )) handler = lsdev.compose_handler(handlers) exec_ = Sfn(executor(useCache=1).process) result = exec_(lsdev(bin, options=['usage', ], handler=handler)) if result: result = result.handler(result) return result == expected_output
def _has_instance_option(self): return bool(findFirst(methodcaller('startswith', '-i'), self.options))