1# Copyright: (c) 2012, Michael DeHaan <michael.dehaan@gmail.com> 2# Copyright: (c) 2012-17, Ansible Project 3# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 5from __future__ import (absolute_import, division, print_function) 6__metaclass__ = type 7 8DOCUMENTATION = """ 9 lookup: template 10 author: Michael DeHaan <michael.dehaan@gmail.com> 11 version_added: "0.9" 12 short_description: retrieve contents of file after templating with Jinja2 13 description: 14 - Returns a list of strings; for each template in the list of templates you pass in, returns a string containing the results of processing that template. 15 options: 16 _terms: 17 description: list of files to template 18 convert_data: 19 type: bool 20 description: whether to convert YAML into data. If False, strings that are YAML will be left untouched. 21 variable_start_string: 22 description: The string marking the beginning of a print statement. 23 default: '{{' 24 version_added: '2.8' 25 type: str 26 variable_end_string: 27 description: The string marking the end of a print statement. 28 default: '}}' 29 version_added: '2.8' 30 type: str 31""" 32 33EXAMPLES = """ 34- name: show templating results 35 debug: 36 msg: "{{ lookup('template', './some_template.j2') }}" 37 38- name: show templating results with different variable start and end string 39 debug: 40 msg: "{{ lookup('template', './some_template.j2', variable_start_string='[%', variable_end_string='%]') }}" 41""" 42 43RETURN = """ 44_raw: 45 description: file(s) content after templating 46""" 47 48from copy import deepcopy 49import os 50 51from ansible.errors import AnsibleError 52from ansible.plugins.lookup import LookupBase 53from ansible.module_utils._text import to_bytes, to_text 54from ansible.template import generate_ansible_template_vars 55from ansible.utils.display import Display 56 57display = Display() 58 59 60class LookupModule(LookupBase): 61 62 def run(self, terms, variables, **kwargs): 63 64 convert_data_p = kwargs.get('convert_data', True) 65 lookup_template_vars = kwargs.get('template_vars', {}) 66 ret = [] 67 68 variable_start_string = kwargs.get('variable_start_string', None) 69 variable_end_string = kwargs.get('variable_end_string', None) 70 71 old_vars = self._templar.available_variables 72 73 for term in terms: 74 display.debug("File lookup term: %s" % term) 75 76 lookupfile = self.find_file_in_search_path(variables, 'templates', term) 77 display.vvvv("File lookup using %s as file" % lookupfile) 78 if lookupfile: 79 b_template_data, show_data = self._loader._get_file_contents(lookupfile) 80 template_data = to_text(b_template_data, errors='surrogate_or_strict') 81 82 # set jinja2 internal search path for includes 83 searchpath = variables.get('ansible_search_path', []) 84 if searchpath: 85 # our search paths aren't actually the proper ones for jinja includes. 86 # We want to search into the 'templates' subdir of each search path in 87 # addition to our original search paths. 88 newsearchpath = [] 89 for p in searchpath: 90 newsearchpath.append(os.path.join(p, 'templates')) 91 newsearchpath.append(p) 92 searchpath = newsearchpath 93 searchpath.insert(0, os.path.dirname(lookupfile)) 94 95 self._templar.environment.loader.searchpath = searchpath 96 if variable_start_string is not None: 97 self._templar.environment.variable_start_string = variable_start_string 98 if variable_end_string is not None: 99 self._templar.environment.variable_end_string = variable_end_string 100 101 # The template will have access to all existing variables, 102 # plus some added by ansible (e.g., template_{path,mtime}), 103 # plus anything passed to the lookup with the template_vars= 104 # argument. 105 vars = deepcopy(variables) 106 vars.update(generate_ansible_template_vars(lookupfile)) 107 vars.update(lookup_template_vars) 108 self._templar.available_variables = vars 109 110 # do the templating 111 res = self._templar.template(template_data, preserve_trailing_newlines=True, 112 convert_data=convert_data_p, escape_backslashes=False) 113 114 ret.append(res) 115 else: 116 raise AnsibleError("the template file %s could not be found for the lookup" % term) 117 118 # restore old variables 119 self._templar.available_variables = old_vars 120 121 return ret 122