def args_to_objects(args):
    r"""
    Run source_to_object() on each element in args and return the result.

    Description of argument(s):
    args                            A type of dictionary, list, set, tuple or simple object whose elements
                                    are to be converted via a call to source_to_object().
    """

    type_of_dict = gp.is_dict(args)
    if type_of_dict:
        if type_of_dict == gp.dict_type():
            return {k: source_to_object(v) for (k, v) in args.items()}
        elif type_of_dict == gp.ordered_dict_type():
            return collections.OrderedDict((k, v) for (k, v) in args.items())
        elif type_of_dict == gp.dot_dict_type():
            return DotDict((k, v) for (k, v) in args.items())
        elif type_of_dict == gp.normalized_dict_type():
            return NormalizedDict((k, v) for (k, v) in args.items())
    # Assume args is list, tuple or set.
    if type(args) in (list, set):
        return [source_to_object(arg) for arg in args]
    elif type(args) is tuple:
        return tuple([source_to_object(arg) for arg in args])

    return source_to_object(args)
Ejemplo n.º 2
0
def nested_get(key_name, structure):
    r"""
    Return a list of all values from the nested structure that have the given
    key name.

    Example:

    Given a dictionary structure named "personnel" with the following contents:

    personnel:
      [manager]:
        [last_name]:             Doe
        [first_name]:            John
      [accountant]:
        [last_name]:             Smith
        [first_name]:            Will

    The following code...

    last_names = nested_get('last_name', personnel)
    print_var(last_names)

    Would result in the following data returned:

    last_names:
      last_names[0]:             Doe
      last_names[1]:             Smith

    Description of argument(s):
    key_name                        The key name (e.g. 'last_name').
    structure                       Any nested combination of lists or
                                    dictionaries (e.g. a dictionary, a
                                    dictionary of dictionaries, a list of
                                    dictionaries, etc.).  This function will
                                    locate the given key at any level within
                                    the structure and include its value in the
                                    returned list.
    """

    result = []
    if type(structure) is list:
        for entry in structure:
            result += nested_get(key_name, entry)
        return result
    elif gp.is_dict(structure):
        for key, value in structure.items():
            result += nested_get(key_name, value)
            if key == key_name:
                result.append(value)

    return result
Ejemplo n.º 3
0
def create_command_string(command, *pos_parms, **options):
    r"""
    Create and return a bash command string consisting of the given arguments
    formatted as text.

    The default formatting of options is as follows:

    <single dash><option name><space delim><option value>

    Example:

    -parm value

    The caller can change the kind of dashes/delimiters used by specifying
    "arg_dashes" and/or "arg_delims" as options.  These options are processed
    specially by the create_command_string function and do NOT get inserted
    into the resulting command string.  All options following the
    arg_dashes/arg_delims options will then use the specified values for
    dashes/delims.  In the special case of arg_dashes equal to "--", the
    arg_delim will automatically be changed to "=".  See examples below.

    Quoting rules:

    The create_command_string function will single quote option values as
    needed to prevent bash expansion.  If the caller wishes to defeat this
    action, they may single or double quote the option value themselves.  See
    examples below.

    pos_parms are NOT automatically quoted.  The caller is advised to either
    explicitly add quotes or to use the quote_bash_parm functions to quote any
    pos_parms.

    Examples:

    command_string = create_command_string('cd', '~')

    Result:
    cd ~

    Note that the pos_parm ("~") does NOT get quoted, as per the
    aforementioned rules.  If quotes are desired, they may be added explicitly
    by the caller:

    command_string = create_command_string('cd', '\'~\'')

    Result:
    cd '~'

    command_string = create_command_string('grep', '\'^[^ ]*=\'',
        '/tmp/myfile', i=None, m='1', arg_dashes='--', color='always')

    Result:
    grep -i -m 1 --color=always '^[^ ]*=' /tmp/myfile

    In the preceding example, note the use of None to cause the "i" parm to be
    treated as a flag (i.e. no argument value is generated).  Also, note the
    use of arg_dashes to change the type of dashes used on all subsequent
    options.  The following example is equivalent to the prior.  Note that
    quote_bash_parm is used instead of including the quotes explicitly.

    command_string = create_command_string('grep', quote_bash_parm('^[^ ]*='),
        '/tmp/myfile', i=None,  m='1', arg_dashes='--', color='always')

    Result:
    grep -i -m 1 --color=always '^[^ ]*=' /tmp/myfile

    In the following example, note the automatic quoting of the password
    option, as per the aforementioned rules.

    command_string = create_command_string('my_pgm', '/tmp/myfile', i=None,
        m='1', arg_dashes='--', password='******')

    However, let's say that the caller wishes to have bash expand the password
    value.  To achieve this, the caller can use double quotes:

    command_string = create_command_string('my_pgm', '/tmp/myfile', i=None,
        m='1', arg_dashes='--', password='******')

    Result:
    my_pgm -i -m 1 --password="******" /tmp/myfile

    command_string = create_command_string('ipmitool', 'power status',
        I='lanplus', C='3', U='root', P='0penBmc', H='wsbmc010')

    Result:
    ipmitool -I lanplus -C 3 -U root -P 0penBmc -H wsbmc010 power status

    By default create_command_string will take measures to preserve the order
    of the callers options.  In some cases, this effort may fail (as when
    calling directly from a robot program).  In this case, the caller can
    accept the responsibility of keeping an ordered list of options by calling
    this function with the last positional parm as some kind of dictionary
    (preferably an OrderedDict) and avoiding the use of any actual option args.

    Example:
    kwargs = collections.OrderedDict([('pass', 0), ('fail', 0)])
    command_string = create_command_string('my program', 'pos_parm1', kwargs)

    Result:

    my program -pass 0 -fail 0 pos_parm1

    Note to programmers who wish to write a wrapper to this function:  If the
    python version is less than 3.6, to get the options to be processed
    correctly, the wrapper function must include a _stack_frame_ix_ keyword
    argument to allow this function to properly re-order options:

    def create_ipmi_ext_command_string(command, **kwargs):

        return create_command_string('ipmitool', command, _stack_frame_ix_=2,
            **kwargs)

    Example call of wrapper function:

    command_string = create_ipmi_ext_command_string('power status',
    I='lanplus')

    Description of argument(s):
    command                         The command (e.g. "cat", "sort",
                                    "ipmitool", etc.).
    pos_parms                       The positional parms for the command (e.g.
                                    PATTERN, FILENAME, etc.).  These will be
                                    placed at the end of the resulting command
                                    string.
    options                         The command options (e.g. "-m 1",
                                    "--max-count=NUM", etc.).  Note that if
                                    the value of any option is None, then it
                                    will be understood to be a flag (for which
                                    no value is required).
    """

    arg_dashes = "-"
    delim = default_arg_delim(arg_dashes)

    command_string = command

    if len(pos_parms) > 0 and gp.is_dict(pos_parms[-1]):
        # Convert pos_parms from tuple to list.
        pos_parms = list(pos_parms)
        # Re-assign options to be the last pos_parm value (which is a
        # dictionary).
        options = pos_parms[-1]
        # Now delete the last pos_parm.
        del pos_parms[-1]
    else:
        # Either get stack_frame_ix from the caller via options or set it to
        # the default value.
        stack_frame_ix = options.pop('_stack_frame_ix_', 1)
        if gm.python_version < gm.ordered_dict_version:
            # Re-establish the original options order as specified on the
            # original line of code.  This function depends on correct order.
            options = re_order_kwargs(stack_frame_ix, **options)
    for key, value in options.items():
        # Check for special values in options and process them.
        if key == "arg_dashes":
            arg_dashes = str(value)
            delim = default_arg_delim(arg_dashes)
            continue
        if key == "arg_delim":
            delim = str(value)
            continue
        # Format the options elements into the command string.
        command_string += " " + arg_dashes + key
        if value is not None:
            command_string += delim
            if re.match(r'^(["].*["]|[\'].*[\'])$', str(value)):
                # Already quoted.
                command_string += str(value)
            else:
                command_string += gm.quote_bash_parm(str(value))
    # Finally, append the pos_parms to the end of the command_string.  Use
    # filter to eliminate blank pos parms.
    command_string = ' '.join([command_string] + list(filter(None, pos_parms)))

    return command_string