From c0f8af520200ac837bd8e7f823f61569c4b74301 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Tue, 16 Apr 2013 18:50:00 -0400 Subject: [PATCH] Make more lookup plugins happy with newstyle variables. Not quite done, but this fixes up with_items/with_nested/file/fileglob. --- lib/ansible/runner/lookup_plugins/file.py | 14 +++++++--- lib/ansible/runner/lookup_plugins/fileglob.py | 22 +++++++--------- lib/ansible/runner/lookup_plugins/items.py | 22 +++++----------- lib/ansible/runner/lookup_plugins/nested.py | 21 +++------------ lib/ansible/utils/__init__.py | 26 +++++++++++++++++++ lib/ansible/utils/template.py | 2 +- 6 files changed, 58 insertions(+), 49 deletions(-) diff --git a/lib/ansible/runner/lookup_plugins/file.py b/lib/ansible/runner/lookup_plugins/file.py index df4a556115..aed322ccb1 100644 --- a/lib/ansible/runner/lookup_plugins/file.py +++ b/lib/ansible/runner/lookup_plugins/file.py @@ -24,13 +24,21 @@ class LookupModule(object): def __init__(self, basedir=None, **kwargs): self.basedir = basedir - def run(self, terms, **kwargs): - if isinstance(terms, basestring): - terms = [ terms ] + def run(self, terms, inject=None, **kwargs): + terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject) ret = [] + + # this can happen if the variable contains a string, strictly not desired for lookup + # plugins, but users may try it, so make it work. + if not isinstance(terms, list): + terms = [ terms ] + for term in terms: path = utils.path_dwim(self.basedir, term) if not os.path.exists(path): raise errors.AnsibleError("%s does not exist" % path) + ret.append(codecs.open(path, encoding="utf8").read().rstrip()) + + return ret diff --git a/lib/ansible/runner/lookup_plugins/fileglob.py b/lib/ansible/runner/lookup_plugins/fileglob.py index 70d202c987..2dd2342d26 100644 --- a/lib/ansible/runner/lookup_plugins/fileglob.py +++ b/lib/ansible/runner/lookup_plugins/fileglob.py @@ -24,18 +24,16 @@ class LookupModule(object): def __init__(self, basedir=None, **kwargs): self.basedir = basedir - def run(self, terms, **kwargs): - if isinstance(terms, basestring): - terms = [ terms ] + def run(self, terms, inject=None, **kwargs): + + utils.listify_lookup_plugin_terms(terms, self.basedir, inject) + ret = [] + for term in terms: - dwimterms = utils.path_dwim(self.basedir, term) - # This skips whatever prefix the dwim added, leaving just the filename for the item - i = -1 - while dwimterms[i] == term[i] and -i < len(term) and -i < len(dwimterms): - i = i - 1 - orig_prefix_len = i + 1 - dwim_prefix_len = len(dwimterms) + i + 1 - ret.extend([ term[:orig_prefix_len] + f[dwim_prefix_len:] - for f in glob.glob(dwimterms) if os.path.isfile(f) ]) + + dwimmed = utils.path_dwim(self.basedir, term) + globbed = glob.glob(dwimmed) + ret.extend(os.path.basename(g) for g in globbed if os.path.isfile(g)) + return ret diff --git a/lib/ansible/runner/lookup_plugins/items.py b/lib/ansible/runner/lookup_plugins/items.py index eaf41a6719..c217521129 100644 --- a/lib/ansible/runner/lookup_plugins/items.py +++ b/lib/ansible/runner/lookup_plugins/items.py @@ -16,7 +16,8 @@ # along with Ansible. If not, see . from ansible.utils import safe_eval -import ansible.utils.template as template +import ansible.utils as utils +import ansible.errors as errors def flatten(terms): ret = [] @@ -33,20 +34,11 @@ class LookupModule(object): self.basedir = basedir def run(self, terms, inject=None, **kwargs): - if isinstance(terms, basestring): - # somewhat did: - # with_items: alist - # OR - # with_items: {{ alist }} - if not '{' in terms and not '[' in terms: - terms = '{{ %s }}' % terms - terms = template.template(self.basedir, terms, inject) - if '{' or '[' in terms: - # Jinja2 already evaluated a variable to a list. - # Jinja2-ified list needs to be converted back to a real type - # TODO: something a bit less heavy than eval - terms = safe_eval(terms) - terms = [ terms ] + terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject) + + if not isinstance(terms, list): + raise errors.AnsibleError("with_items expects a list") + return flatten(terms) diff --git a/lib/ansible/runner/lookup_plugins/nested.py b/lib/ansible/runner/lookup_plugins/nested.py index 70f606adbd..f96a37d4b4 100644 --- a/lib/ansible/runner/lookup_plugins/nested.py +++ b/lib/ansible/runner/lookup_plugins/nested.py @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . -import ansible.utils.template as template +import ansible.utils as utils from ansible.utils import safe_eval import ansible.errors as errors @@ -46,28 +46,13 @@ class LookupModule(object): # this code is common with 'items.py' consider moving to utils if we need it again - if isinstance(terms, basestring): - # someone did: - # with_items: alist - # OR - # with_items: {{ alist }} - if not '{' in terms and not '[' in terms: - terms = '{{ %s }}' % terms - terms = template.template(self.basedir, terms, inject) - if '{' or '[' in terms: - # Jinja2 already evaluated a variable to a list. - # Jinja2-ified list needs to be converted back to a real type - # TODO: something a bit less heavy than eval - terms = safe_eval(terms) - - if not isinstance(terms, list): - raise errors.AnsibleError("a list is required for with_nested") + terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject) my_list = terms[:] my_list.reverse() result = [] if len(my_list) == 0: - raise errors.AnsibleError("with_nested requires at least one list") + raise errors.AnsibleError("with_nested requires at least one element in the nested list") result = my_list.pop() while len(my_list) > 0: result2 = combine(result, my_list.pop()) diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index 28e1ea34e7..06ae73bf0b 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -26,6 +26,7 @@ import operator from ansible import errors from ansible import __version__ from ansible.utils.plugins import * +from ansible.utils import template import ansible.constants as C import time import StringIO @@ -713,6 +714,31 @@ def safe_eval(str): return str +def listify_lookup_plugin_terms(terms, basedir, inject): + + if isinstance(terms, basestring): + print "A0" + # somewhat did: + # with_items: alist + # OR + # with_items: {{ alist }} + + if not '{' in terms and not '[' in terms and not terms.strip().startswith("/"): + try: + terms = template.template(basedir, "{{ %s }}" % terms, inject) + except: + pass + + if '{' or '[' in terms: + # Jinja2 already evaluated a variable to a list. + # Jinja2-ified list needs to be converted back to a real type + # TODO: something a bit less heavy than eval + return safe_eval(terms) + + if isinstance(terms, basestring): + terms = [ terms ] + + return terms diff --git a/lib/ansible/utils/template.py b/lib/ansible/utils/template.py index 78b6487642..8faa4f344c 100644 --- a/lib/ansible/utils/template.py +++ b/lib/ansible/utils/template.py @@ -23,7 +23,6 @@ from jinja2.runtime import StrictUndefined import yaml import json from ansible import errors -import ansible.utils as utils import ansible.constants as C import time import subprocess @@ -41,6 +40,7 @@ _LISTRE = re.compile(r"(\w+)\[(\d+)\]") JINJA2_OVERRIDE='#jinja2:' def lookup(name, *args, **kwargs): + from ansible import utils instance = utils.plugins.lookup_loader.get(name.lower(), basedir=kwargs.get('basedir',None)) if instance is not None: return ",".join(instance.run(*args, inject=vars, **kwargs))