Пример #1
0
    def main(args):
        # Retrieve the intersphinx information from the sphinx config file
        conf_dir = pathlib.Path(args.conf_file).parent

        conf_module_spec = importlib.util.spec_from_file_location(
            'sphinxconf', args.conf_file)
        conf_module = importlib.util.module_from_spec(conf_module_spec)
        conf_module_spec.loader.exec_module(conf_module)
        intersphinx_mapping = conf_module.intersphinx_mapping

        for intersphinx_name, inventory in intersphinx_mapping.items():
            if not is_iterable(inventory) or len(inventory) != 2:
                print('WARNING: The intersphinx entry for {0} must be'
                      ' a two-tuple.\n{1}'.format(intersphinx_name,
                                                  EXAMPLE_CONF))
                continue

            url = cache_file = None
            for inv_source in inventory:
                if isinstance(inv_source, str) and url is None:
                    url = inv_source
                elif is_iterable(inv_source) and cache_file is None:
                    if len(inv_source) != 2:
                        print(
                            'WARNING: The fallback entry for {0} should be a tuple of (None,'
                            ' filename).\n{1}'.format(intersphinx_name,
                                                      EXAMPLE_CONF))
                        continue
                    cache_file = inv_source[1]
                else:
                    print(
                        'WARNING: The configuration for {0} should be a tuple of one url and one'
                        ' tuple for a fallback filename.\n{1}'.format(
                            intersphinx_name, EXAMPLE_CONF))
                    continue

            if url is None or cache_file is None:
                print('WARNING: Could not figure out the url or fallback'
                      ' filename for {0}.\n{1}'.format(intersphinx_name,
                                                       EXAMPLE_CONF))
                continue

            url = urllib.parse.urljoin(url, 'objects.inv')
            # Resolve any relative cache files to be relative to the conf file
            cache_file = conf_dir / cache_file

            # Retrieve the inventory and cache it
            # The jinja CDN seems to be blocking the default urllib User-Agent
            requestor = Request(
                headers={'User-Agent': 'Definitely Not Python ;-)'})
            with requestor.open('GET', url) as source_file:
                with open(cache_file, 'wb') as f:
                    f.write(source_file.read())

        print(
            'Download of new cache files complete.  Remember to git commit -a the changes'
        )

        return 0
Пример #2
0
def handle_aliases(argument_spec, params):
    """Return a two item tuple. The first is a dictionary of aliases, the second is
    a list of legal inputs."""

    legal_inputs = ['_ansible_%s' % k for k in PASS_VARS]
    aliases_results = {}  # alias:canon

    for (k, v) in argument_spec.items():
        legal_inputs.append(k)
        aliases = v.get('aliases', None)
        default = v.get('default', None)
        required = v.get('required', False)
        if default is not None and required:
            # not alias specific but this is a good place to check this
            raise ValueError("internal error: required and default are mutually exclusive for %s" % k)
        if aliases is None:
            continue
        if not is_iterable(aliases) or isinstance(aliases, (binary_type, text_type)):
            raise TypeError('internal error: aliases must be a list or tuple')
        for alias in aliases:
            legal_inputs.append(alias)
            aliases_results[alias] = k
            if alias in params:
                params[k] = params[alias]

    return aliases_results, legal_inputs
Пример #3
0
def check_option_choices(v):
    # Check whether choices have the correct type
    v_choices = v.get('choices')
    if not is_iterable(v_choices):
        return v

    if v.get('type') == 'list':
        # choices for a list type means that every list element must be one of these choices
        type_checker, type_name = get_type_checker({'type': v.get('elements')})
    else:
        type_checker, type_name = get_type_checker(v)
    if type_checker is None:
        return v

    for value in v_choices:
        try:
            type_checker(value)
        except Exception as exc:
            raise _add_ansible_error_code(Invalid(
                'Argument defines choices as (%r) but this is incompatible with argument type %s: %s'
                % (value, type_name, exc)),
                                          error_code=
                                          'doc-choices-incompatible-type')

    return v
Пример #4
0
def author(value):

    if not is_iterable(value):
        value = [value]

    for line in value:
        m = author_line.search(line)
        if not m:
            raise Invalid("Invalid author")
Пример #5
0
def _handle_aliases(argument_spec, parameters, alias_warnings=None, alias_deprecations=None):
    """Process aliases from an argument_spec including warnings and deprecations.

    Modify ``parameters`` by adding a new key for each alias with the supplied
    value from ``parameters``.

    If a list is provided to the alias_warnings parameter, it will be filled with tuples
    (option, alias) in every case where both an option and its alias are specified.

    If a list is provided to alias_deprecations, it will be populated with dictionaries,
    each containing deprecation information for each alias found in argument_spec.

    :param argument_spec: Dictionary of parameters, their type, and valid values.
    :type argument_spec: dict

    :param parameters: Dictionary of parameters.
    :type parameters: dict

    :param alias_warnings:
    :type alias_warnings: list

    :param alias_deprecations:
    :type alias_deprecations: list
    """

    aliases_results = {}  # alias:canon

    for (k, v) in argument_spec.items():
        aliases = v.get('aliases', None)
        default = v.get('default', None)
        required = v.get('required', False)

        if alias_deprecations is not None:
            for alias in argument_spec[k].get('deprecated_aliases', []):
                if alias.get('name') in parameters:
                    alias_deprecations.append(alias)

        if default is not None and required:
            # not alias specific but this is a good place to check this
            raise ValueError("internal error: required and default are mutually exclusive for %s" % k)

        if aliases is None:
            continue

        if not is_iterable(aliases) or isinstance(aliases, (binary_type, text_type)):
            raise TypeError('internal error: aliases must be a list or tuple')

        for alias in aliases:
            aliases_results[alias] = k
            if alias in parameters:
                if k in parameters and alias_warnings is not None:
                    alias_warnings.append((k, alias))
                parameters[k] = parameters[alias]

    return aliases_results
Пример #6
0
    def count_terms(self, terms, module_parameters):
        """Count the number of occurrences of a key in a given dictionary
        :arg terms: String or iterable of values to check
        :arg module_parameters: Dictionary of module parameters
        :returns: An integer that is the number of occurrences of the terms values
            in the provided dictionary.
        """

        if not is_iterable(terms):
            terms = [terms]

        return len(set(terms).intersection(module_parameters))
Пример #7
0
def author(value):
    if value is None:
        return value  # let schema checks handle

    if not is_iterable(value):
        value = [value]

    for line in value:
        if not isinstance(line, string_types):
            continue  # let schema checks handle
        m = author_line.search(line)
        if not m:
            raise Invalid("Invalid author")

    return value
Пример #8
0
def handle_aliases(argument_spec, parameters, alias_warnings=None, alias_deprecations=None):
    """Return a two item tuple. The first is a dictionary of aliases, the second is
    a list of legal inputs.

    Modify supplied parameters by adding a new key for each alias.

    If a list is provided to the alias_warnings parameter, it will be filled with tuples
    (option, alias) in every case where both an option and its alias are specified.

    If a list is provided to alias_deprecations, it will be populated with dictionaries,
    each containing deprecation information for each alias found in argument_spec.
    """

    legal_inputs = ['_ansible_%s' % k for k in PASS_VARS]
    aliases_results = {}  # alias:canon

    for (k, v) in argument_spec.items():
        legal_inputs.append(k)
        aliases = v.get('aliases', None)
        default = v.get('default', None)
        required = v.get('required', False)

        if alias_deprecations is not None:
            for alias in argument_spec[k].get('deprecated_aliases', []):
                if alias.get('name') in parameters:
                    alias_deprecations.append(alias)

        if default is not None and required:
            # not alias specific but this is a good place to check this
            raise ValueError("internal error: required and default are mutually exclusive for %s" % k)

        if aliases is None:
            continue

        if not is_iterable(aliases) or isinstance(aliases, (binary_type, text_type)):
            raise TypeError('internal error: aliases must be a list or tuple')

        for alias in aliases:
            legal_inputs.append(alias)
            aliases_results[alias] = k
            if alias in parameters:
                if k in parameters and alias_warnings is not None:
                    alias_warnings.append((k, alias))
                parameters[k] = parameters[alias]

    return aliases_results, legal_inputs
Пример #9
0
def _return_datastructure_name(obj):
    """ Return native stringified values from datastructures.

    For use with removing sensitive values pre-jsonification."""
    if isinstance(obj, (text_type, binary_type)):
        if obj:
            yield to_native(obj, errors='surrogate_or_strict')
        return
    elif isinstance(obj, Mapping):
        for element in obj.items():
            for subelement in _return_datastructure_name(element[1]):
                yield subelement
    elif is_iterable(obj):
        for element in obj:
            for subelement in _return_datastructure_name(element):
                yield subelement
    elif isinstance(obj, (bool, NoneType)):
        # This must come before int because bools are also ints
        return
    elif isinstance(obj, tuple(list(integer_types) + [float])):
        yield to_native(obj, nonstring='simplerepr')
    else:
        raise TypeError('Unknown parameter type: %s' % (type(obj)))
Пример #10
0
def main():

    # the command module is the one ansible module that does not take key=value args
    # hence don't copy this one if you are looking to build others!
    module = AnsibleModule(
        argument_spec=dict(
            _raw_params=dict(),
            _uses_shell=dict(type='bool', default=False),
            argv=dict(type='list'),
            chdir=dict(type='path'),
            executable=dict(),
            creates=dict(type='path'),
            removes=dict(type='path'),
            # The default for this really comes from the action plugin
            warn=dict(type='bool', default=True),
            stdin=dict(required=False),
        ),
        supports_check_mode=True,
    )
    shell = module.params['_uses_shell']
    chdir = module.params['chdir']
    executable = module.params['executable']
    args = module.params['_raw_params']
    argv = module.params['argv']
    creates = module.params['creates']
    removes = module.params['removes']
    warn = module.params['warn']
    stdin = module.params['stdin']

    if not shell and executable:
        module.warn(
            "As of Ansible 2.4, the parameter 'executable' is no longer supported with the 'command' module. Not using '%s'."
            % executable)
        executable = None

    if (not args or args.strip() == '') and not argv:
        module.fail_json(rc=256, msg="no command given")

    if args and argv:
        module.fail_json(rc=256,
                         msg="only command or argv can be given, not both")

    if not shell and args:
        args = shlex.split(args)

    args = args or argv

    # All args must be strings
    if is_iterable(args, include_strings=False):
        args = [
            to_native(arg,
                      errors='surrogate_or_strict',
                      nonstring='simplerepr') for arg in args
        ]

    if chdir:
        chdir = os.path.abspath(chdir)
        os.chdir(chdir)

    if creates:
        # do not run the command if the line contains creates=filename
        # and the filename already exists.  This allows idempotence
        # of command executions.
        if glob.glob(creates):
            module.exit_json(cmd=args,
                             stdout="skipped, since %s exists" % creates,
                             changed=False,
                             rc=0)

    if removes:
        # do not run the command if the line contains removes=filename
        # and the filename does not exist.  This allows idempotence
        # of command executions.
        if not glob.glob(removes):
            module.exit_json(cmd=args,
                             stdout="skipped, since %s does not exist" %
                             removes,
                             changed=False,
                             rc=0)

    if warn:
        check_command(module, args)

    startd = datetime.datetime.now()

    if not module.check_mode:
        rc, out, err = module.run_command(args,
                                          executable=executable,
                                          use_unsafe_shell=shell,
                                          encoding=None,
                                          data=stdin)
    elif creates or removes:
        rc = 0
        out = err = b'Command would have run if not in check mode'
    else:
        module.exit_json(msg="skipped, running in check mode", skipped=True)

    endd = datetime.datetime.now()
    delta = endd - startd

    result = dict(
        cmd=args,
        stdout=out.rstrip(b"\r\n"),
        stderr=err.rstrip(b"\r\n"),
        rc=rc,
        start=str(startd),
        end=str(endd),
        delta=str(delta),
        changed=True,
    )

    if rc != 0:
        module.fail_json(msg='non-zero return code', **result)

    module.exit_json(**result)
Пример #11
0
def main():

    # the command module is the one ansible module that does not take key=value args
    # hence don't copy this one if you are looking to build others!
    # NOTE: ensure splitter.py is kept in sync for exceptions
    module = AnsibleModule(
        argument_spec=dict(
            _raw_params=dict(),
            _uses_shell=dict(type='bool', default=False),
            argv=dict(type='list', elements='str'),
            chdir=dict(type='path'),
            executable=dict(),
            creates=dict(type='path'),
            removes=dict(type='path'),
            # The default for this really comes from the action plugin
            stdin=dict(required=False),
            stdin_add_newline=dict(type='bool', default=True),
            strip_empty_ends=dict(type='bool', default=True),
        ),
        supports_check_mode=True,
    )
    shell = module.params['_uses_shell']
    chdir = module.params['chdir']
    executable = module.params['executable']
    args = module.params['_raw_params']
    argv = module.params['argv']
    creates = module.params['creates']
    removes = module.params['removes']
    stdin = module.params['stdin']
    stdin_add_newline = module.params['stdin_add_newline']
    strip = module.params['strip_empty_ends']

    # we promissed these in 'always' ( _lines get autoaded on action plugin)
    r = {
        'changed': False,
        'stdout': '',
        'stderr': '',
        'rc': None,
        'cmd': None,
        'start': None,
        'end': None,
        'delta': None,
        'msg': ''
    }

    if not shell and executable:
        module.warn(
            "As of Ansible 2.4, the parameter 'executable' is no longer supported with the 'command' module. Not using '%s'."
            % executable)
        executable = None

    if (not args or args.strip() == '') and not argv:
        r['rc'] = 256
        r['msg'] = "no command given"
        module.fail_json(**r)

    if args and argv:
        r['rc'] = 256
        r['msg'] = "only command or argv can be given, not both"
        module.fail_json(**r)

    if not shell and args:
        args = shlex.split(args)

    args = args or argv
    # All args must be strings
    if is_iterable(args, include_strings=False):
        args = [
            to_native(arg,
                      errors='surrogate_or_strict',
                      nonstring='simplerepr') for arg in args
        ]

    r['cmd'] = args

    if chdir:
        chdir = to_bytes(chdir, errors='surrogate_or_strict')

        try:
            os.chdir(chdir)
        except (IOError, OSError) as e:
            r['msg'] = 'Unable to change directory before execution: %s' % to_text(
                e)
            module.fail_json(**r)

    # check_mode partial support, since it only really works in checking creates/removes
    if module.check_mode:
        shoulda = "Would"
    else:
        shoulda = "Did"

    # special skips for idempotence if file exists (assumes command creates)
    if creates:
        if glob.glob(creates):
            r['msg'] = "%s not run command since '%s' exists" % (shoulda,
                                                                 creates)
            r['stdout'] = "skipped, since %s exists" % creates  # TODO: deprecate

            r['rc'] = 0

    # special skips for idempotence if file does not exist (assumes command removes)
    if not r['msg'] and removes:
        if not glob.glob(removes):
            r['msg'] = "%s not run command since '%s' does not exist" % (
                shoulda, removes)
            r['stdout'] = "skipped, since %s does not exist" % removes  # TODO: deprecate
            r['rc'] = 0

    if r['msg']:
        module.exit_json(**r)

    r['changed'] = True

    # actually executes command (or not ...)
    if not module.check_mode:
        r['start'] = datetime.datetime.now()
        r['rc'], r['stdout'], r['stderr'] = module.run_command(
            args,
            executable=executable,
            use_unsafe_shell=shell,
            encoding=None,
            data=stdin,
            binary_data=(not stdin_add_newline))
        r['end'] = datetime.datetime.now()
    else:
        # this is partial check_mode support, since we end up skipping if we get here
        r['rc'] = 0
        r['msg'] = "Command would have run if not in check mode"
        if creates is None and removes is None:
            r['skipped'] = True
            # skipped=True and changed=True are mutually exclusive
            r['changed'] = False

    # convert to text for jsonization and usability
    if r['start'] is not None and r['end'] is not None:
        # these are datetime objects, but need them as strings to pass back
        r['delta'] = to_text(r['end'] - r['start'])
        r['end'] = to_text(r['end'])
        r['start'] = to_text(r['start'])

    if strip:
        r['stdout'] = to_text(r['stdout']).rstrip("\r\n")
        r['stderr'] = to_text(r['stderr']).rstrip("\r\n")

    if r['rc'] != 0:
        r['msg'] = 'non-zero return code'
        module.fail_json(**r)

    module.exit_json(**r)
Пример #12
0
 def path_list_checker(value):
     if not isinstance(value, string_types) and not is_iterable(value):
         raise ValueError('Value must be string or list of strings')
Пример #13
0
def test_iterable_including_strings(string_input):
    assert is_iterable(string_input, include_strings=True)
Пример #14
0
def test_iterable_negative(seq):
    assert not is_iterable(seq)
Пример #15
0
def test_iterable_positive(seq):
    assert is_iterable(seq)
Пример #16
0
def test_iterable_excluding_strings(string_input):
    assert not is_iterable(string_input, include_strings=False)