Ejemplo n.º 1
0
    def _lookup(self, name, *args, **kwargs):
        instance = self._lookup_loader.get(name.lower(),
                                           loader=self._loader,
                                           templar=self)

        if instance is not None:
            wantlist = kwargs.pop('wantlist', False)
            allow_unsafe = kwargs.pop('allow_unsafe',
                                      C.DEFAULT_ALLOW_UNSAFE_LOOKUPS)

            from ansible.utils.listify import listify_lookup_plugin_terms
            loop_terms = listify_lookup_plugin_terms(terms=args,
                                                     templar=self,
                                                     loader=self._loader,
                                                     fail_on_undefined=True,
                                                     convert_bare=False)
            # safely catch run failures per #5059
            try:
                ran = instance.run(loop_terms,
                                   variables=self._available_variables,
                                   **kwargs)
            except (AnsibleUndefinedVariable, UndefinedError) as e:
                raise AnsibleUndefinedVariable(e)
            except Exception as e:
                if self._fail_on_lookup_errors:
                    raise AnsibleError(
                        "An unhandled exception occurred while running the lookup plugin '%s'. Error was a %s, "
                        "original message: %s" % (name, type(e), e))
                ran = None

            if ran and not allow_unsafe:
                if wantlist:
                    ran = wrap_var(ran)
                else:
                    try:
                        ran = UnsafeProxy(",".join(ran))
                    except TypeError:
                        # Lookup Plugins should always return lists.  Throw an error if that's not
                        # the case:
                        if not isinstance(ran, Sequence):
                            raise AnsibleError(
                                "The lookup plugin '%s' did not return a list."
                                % name)

                        # The TypeError we can recover from is when the value *inside* of the list
                        # is not a string
                        if len(ran) == 1:
                            ran = wrap_var(ran[0])
                        else:
                            ran = wrap_var(ran)

                if self.cur_context:
                    self.cur_context.unsafe = True
            return ran
        else:
            raise AnsibleError("lookup plugin (%s) not found" % name)
Ejemplo n.º 2
0
    def _lookup(self, name, *args, **kwargs):
        instance = self._lookup_loader.get(name.lower(),
                                           loader=self._loader,
                                           templar=self)

        if instance is not None:
            wantlist = kwargs.pop('wantlist', False)

            from ansible.utils.listify import listify_lookup_plugin_terms
            loop_terms = listify_lookup_plugin_terms(terms=args,
                                                     templar=self,
                                                     loader=self._loader,
                                                     fail_on_undefined=True,
                                                     convert_bare=False)
            # safely catch run failures per #5059
            try:
                ran = instance.run(loop_terms,
                                   variables=self._available_variables,
                                   **kwargs)
            except (AnsibleUndefinedVariable, UndefinedError) as e:
                raise AnsibleUndefinedVariable(e)
            except Exception as e:
                if self._fail_on_lookup_errors:
                    raise AnsibleError(
                        "An unhandled exception occurred while running the lookup plugin '%s'. Error was a %s, "
                        "original message: %s" % (name, type(e), e))
                ran = None

            if ran:
                if wantlist:
                    ran = wrap_var(ran)
                else:
                    try:
                        ran = UnsafeProxy(",".join(ran))
                    except TypeError:
                        if isinstance(ran, list) and len(ran) == 1:
                            ran = wrap_var(ran[0])
                        else:
                            ran = wrap_var(ran)

            return ran
        else:
            raise AnsibleError("lookup plugin (%s) not found" % name)
Ejemplo n.º 3
0
    def _get_loop_items(self):
        '''
        Loads a lookup plugin to handle the with_* portion of a task (if specified),
        and returns the items result.
        '''

        # save the play context variables to a temporary dictionary,
        # so that we can modify the job vars without doing a full copy
        # and later restore them to avoid modifying things too early
        play_context_vars = dict()
        self._play_context.update_vars(play_context_vars)

        old_vars = dict()
        for k in play_context_vars:
            if k in self._job_vars:
                old_vars[k] = self._job_vars[k]
            self._job_vars[k] = play_context_vars[k]

        # get search path for this task to pass to lookup plugins
        self._job_vars['ansible_search_path'] = self._task.get_search_path()

        templar = Templar(loader=self._loader,
                          shared_loader_obj=self._shared_loader_obj,
                          variables=self._job_vars)
        items = None
        if self._task.loop:
            if self._task.loop in self._shared_loader_obj.lookup_loader:
                fail = True
                if self._task.loop == 'first_found':
                    # first_found loops are special. If the item is undefined then we want to fall through to the next value rather than failing.
                    fail = False

                loop_terms = listify_lookup_plugin_terms(
                    terms=self._task.loop_args,
                    templar=templar,
                    loader=self._loader,
                    fail_on_undefined=fail,
                    convert_bare=False)
                if not fail:
                    loop_terms = [
                        t for t in loop_terms if not templar._contains_vars(t)
                    ]

                # get lookup
                mylookup = self._shared_loader_obj.lookup_loader.get(
                    self._task.loop, loader=self._loader, templar=templar)

                # give lookup task 'context' for subdir (mostly needed for first_found)
                for subdir in ['template', 'var',
                               'file']:  # TODO: move this to constants?
                    if subdir in self._task.action:
                        break
                setattr(mylookup, '_subdir', subdir + 's')

                # run lookup
                items = mylookup.run(terms=loop_terms,
                                     variables=self._job_vars,
                                     wantlist=True)
            else:
                raise AnsibleError(
                    "Unexpected failure in finding the lookup named '%s' in the available lookup plugins"
                    % self._task.loop)

        # now we restore any old job variables that may have been modified,
        # and delete them if they were in the play context vars but not in
        # the old variables dictionary
        for k in play_context_vars:
            if k in old_vars:
                self._job_vars[k] = old_vars[k]
            else:
                del self._job_vars[k]

        if items:
            for idx, item in enumerate(items):
                if item is not None and not isinstance(item, UnsafeProxy):
                    items[idx] = UnsafeProxy(item)

        # ensure basedir is always in (dwim already searches here but we need to display it)
        if self._loader.get_basedir(
        ) not in self._job_vars['ansible_search_path']:
            self._job_vars['ansible_search_path'].append(
                self._loader.get_basedir())

        return items
Ejemplo n.º 4
0
def test_UnsafeProxy():
    assert isinstance(UnsafeProxy({}), dict)
    assert not isinstance(UnsafeProxy({}), AnsibleUnsafe)

    assert isinstance(UnsafeProxy('foo'), AnsibleUnsafeText)