mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
cleanup example config file + Squashed commit of the following:
commit c36b66dc952dfff91043ecbca56cf3f1f8f00703 Merge:240d7bf
f4cf934 Author: Michael DeHaan <michael@ansibleworks.com> Date: Tue Jun 18 13:04:51 2013 -0400 Merge branch 'unevaluated-vars' of git://github.com/lorin/ansible into lorin_undefined Conflicts: lib/ansible/runner/__init__.py commit f4cf93436767f73b62a16067ab5e628830045896 Merge: 253144007a1365
Author: Lorin Hochstein <lorin@nimbisservices.com> Date: Thu Jun 6 11:07:41 2013 -0400 Merge branch 'devel' into unevaluated-vars commit 253144045cbafd7d72836f1017c62ac4ba623186 Author: Lorin Hochstein <lorin@nimbisservices.com> Date: Thu Jun 6 11:06:37 2013 -0400 Fail template from file on undefined vars If config option is set, raise an exception if templating from a file and a variable is undefined. commit aecb71d8b75257f0f3e11a9b176fc3737aecef8d Author: Lorin Hochstein <lorin@nimbisservices.com> Date: Wed Jun 5 17:12:12 2013 -0400 Add fail_on_undefined flag Add a fail_on_undefined flag to the template and template_from_string methods. If this flag is true, then re-raise the ninja2.excpetions.UndefinedError instead of swallowing it. commit cbb1808f0585f01536240aee05a1bfd06c4b4647 Merge: d4bbf4941425fb
Author: Lorin Hochstein <lorin@nimbisservices.com> Date: Wed Jun 5 16:14:12 2013 -0400 Merge branch 'devel' into unevaluated-vars commit d4bbf492b0b63c789d66ab60d0ec634d100fca82 Author: Lorin Hochstein <lorin@nimbisservices.com> Date: Mon Jun 3 19:46:13 2013 -0400 template: Raise UndefinedError exception In template_from_string, raise an undefined error if it occurs. Have the caller catch it and throw an AnsibleUndefinedVariable commit c94780280515f1f3756fdc429b2b1e87b365e9b7 Merge: 8d919d6be33bcf
Author: Lorin Hochstein <lorin@nimbisservices.com> Date: Mon Jun 3 10:09:43 2013 -0400 Merge branch 'devel' into unevaluated-vars commit 8d919d6c97b28a42f47ca7248c542695baf6175f Merge: 0f68ad8b8630d2
Author: Lorin Hochstein <lorin@nimbisservices.com> Date: Thu May 30 16:27:48 2013 -0400 Merge branch 'devel' into unevaluated-vars commit 0f68ad8193ac17488e339a258f8c63fdae399c26 Author: Lorin Hochstein <lorin@nimbisservices.com> Date: Thu May 30 14:32:03 2013 -0400 Optionally fail task on undefined variables This patch introduces a new configuration option called error_on_undefined_vars, which defaults to false. If this option is set to true, then a task which has unevaluated variables in its arguments will fail instead of running. Output looks like this: TASK: [set rabbitmq password] ************************************************* fatal: [10.20.0.7] => Undefined variables: rabbitmq_user, rabbitmq_password
This commit is contained in:
parent
240d7bf197
commit
637983cf31
5 changed files with 102 additions and 144 deletions
|
@ -1,138 +1,75 @@
|
||||||
# config file for ansible -- http://ansible.github.com
|
# config file for ansible -- http://ansibleworks.com/
|
||||||
#
|
# ==================================================
|
||||||
# nearly all parameters can be overridden in ansible-playbook or with command line flags
|
|
||||||
# ansible will read ~/.ansible.cfg, ansible.cfg in the current working directory or
|
# nearly all parameters can be overridden in ansible-playbook
|
||||||
|
# or with command line flags. ansible will read ~/.ansible.cfg,
|
||||||
|
# ansible.cfg in the current working directory or
|
||||||
# /etc/ansible/ansible.cfg, whichever it finds first
|
# /etc/ansible/ansible.cfg, whichever it finds first
|
||||||
|
|
||||||
[defaults]
|
[defaults]
|
||||||
|
|
||||||
# location of inventory file, eliminates need to specify -i
|
# some basic default values...
|
||||||
|
|
||||||
hostfile = /etc/ansible/hosts
|
hostfile = /etc/ansible/hosts
|
||||||
|
library = /usr/share/ansible
|
||||||
|
remote_tmp = $HOME/.ansible/tmp
|
||||||
|
pattern = *
|
||||||
|
forks = 5
|
||||||
|
poll_interval = 15
|
||||||
|
sudo_user = root
|
||||||
|
#ask_sudo_pass = True
|
||||||
|
#ask_pass = True
|
||||||
|
transport = paramiko
|
||||||
|
remote_port = 22
|
||||||
|
|
||||||
# location of ansible library, eliminates need to specify --module-path
|
# change this for alternative sudo implementations
|
||||||
|
sudo_exe = sudo
|
||||||
|
|
||||||
library = /usr/share/ansible
|
# what flags to pass to sudo
|
||||||
|
|
||||||
# default module name used in /usr/bin/ansible when -m is not specified
|
|
||||||
|
|
||||||
module_name = command
|
|
||||||
|
|
||||||
# location for ansible log file. If set, will store output from ansible
|
|
||||||
# and ansible-playbook. If enabling, you may wish to configure
|
|
||||||
# logrotate.
|
|
||||||
|
|
||||||
#log_path = /var/log/ansible.log
|
|
||||||
|
|
||||||
# home directory where temp files are stored on remote systems. Should
|
|
||||||
# almost always contain $HOME or be a directory writeable by all users
|
|
||||||
|
|
||||||
remote_tmp = $HOME/.ansible/tmp
|
|
||||||
|
|
||||||
# the default pattern for ansible-playbooks ("hosts:")
|
|
||||||
|
|
||||||
pattern = *
|
|
||||||
|
|
||||||
# the default number of forks (parallelism) to be used. Usually you
|
|
||||||
# can crank this up.
|
|
||||||
|
|
||||||
forks=5
|
|
||||||
|
|
||||||
# the timeout used by various connection types. Usually this corresponds
|
|
||||||
# to an SSH timeout
|
|
||||||
|
|
||||||
timeout=10
|
|
||||||
|
|
||||||
# when using --poll or "poll:" in an ansible playbook, and not specifying
|
|
||||||
# an explicit poll interval, use this interval
|
|
||||||
|
|
||||||
poll_interval=15
|
|
||||||
|
|
||||||
# when specifying --sudo to /usr/bin/ansible or "sudo:" in a playbook,
|
|
||||||
# and not specifying "--sudo-user" or "sudo_user" respectively, sudo
|
|
||||||
# to this user account
|
|
||||||
|
|
||||||
sudo_user=root
|
|
||||||
|
|
||||||
# the following forces ansible to always ask for the sudo password (instead of having
|
|
||||||
# to add -K to the commandline). Or you can use the environment variable (ANSIBLE_ASK_SUDO_PASS)
|
|
||||||
|
|
||||||
#ask_sudo_pass=True
|
|
||||||
|
|
||||||
# the following forces ansible to always ask for the ssh-password (-k)
|
|
||||||
# can also be set by the environment variable ANSIBLE_ASK_PASS
|
|
||||||
|
|
||||||
#ask_pass=True
|
|
||||||
|
|
||||||
# connection to use when -c <connection_type> is not specified
|
|
||||||
|
|
||||||
transport=paramiko
|
|
||||||
|
|
||||||
# remote SSH port to be used when --port or "port:" or an equivalent inventory
|
|
||||||
# variable is not specified.
|
|
||||||
|
|
||||||
remote_port=22
|
|
||||||
|
|
||||||
# if set, always run /usr/bin/ansible commands as this user, and assume this value
|
|
||||||
# if "user:" is not set in a playbook. If not set, use the current Unix user
|
|
||||||
# as the default
|
|
||||||
|
|
||||||
#remote_user=root
|
|
||||||
|
|
||||||
# the default sudo executable. If a sudo alternative with a sudo-compatible interface
|
|
||||||
# is used, specify its executable name as the default
|
|
||||||
|
|
||||||
sudo_exe=sudo
|
|
||||||
|
|
||||||
# the default flags passed to sudo
|
|
||||||
# sudo_flags=-H
|
# sudo_flags=-H
|
||||||
|
|
||||||
# all commands executed under sudo are passed as arguments to a shell command
|
# SSH timeout
|
||||||
# This shell command defaults to /bin/sh
|
timeout = 10
|
||||||
# Changing this helps the situation where a user is only allowed to run
|
|
||||||
# e.g. /bin/bash with sudo privileges
|
|
||||||
|
|
||||||
|
# default user to use for playbooks if user is not specified
|
||||||
|
# (/usr/bin/ansible will use current user as default)
|
||||||
|
remote_user=root
|
||||||
|
|
||||||
|
# logging is off by default unless this path is defined
|
||||||
|
# if so defined, consider logrotate
|
||||||
|
# log_path = /var/log/ansible.log
|
||||||
|
|
||||||
|
# default module name for /usr/bin/ansible
|
||||||
|
module_name = command
|
||||||
|
|
||||||
|
# use this shell for commands executed under sudo
|
||||||
|
# you may need to change this to bin/bash in rare instances
|
||||||
|
# if sudo is constrained
|
||||||
# executable = /bin/sh
|
# executable = /bin/sh
|
||||||
|
|
||||||
# how to handle hash defined in several places
|
# if inventory variables overlap, does the higher precedence one win
|
||||||
# hash can be merged, or replaced
|
# or are hash values merged together? The default is 'replace' but
|
||||||
# if you use replace, and have multiple hashes named 'x', the last defined
|
# this can also be set to 'merge'.
|
||||||
# will override the previously defined one
|
|
||||||
# if you use merge here, hash will cumulate their keys, but keys will still
|
|
||||||
# override each other
|
|
||||||
# replace is the default value, and is how ansible always handled hash variables
|
|
||||||
#
|
|
||||||
# hash_behaviour=replace
|
# hash_behaviour=replace
|
||||||
|
|
||||||
# How to handle variable replacement - as of 1.2, Jinja2 variable syntax is
|
# How to handle variable replacement - as of 1.2, Jinja2 variable syntax is
|
||||||
# preferred, but we still support the old $variable replacement too.
|
# preferred, but we still support the old $variable replacement too.
|
||||||
# If you change legacy_playbook_variables to no then Ansible will no longer
|
# Turn off ${old_style} variables here if you like.
|
||||||
# try to do replacement on $variable style variables.
|
|
||||||
#
|
|
||||||
# legacy_playbook_variables=yes
|
# legacy_playbook_variables=yes
|
||||||
|
|
||||||
# if you need to use jinja2 extensions, you can list them here
|
# list any Jinja2 extensions to enable here:
|
||||||
# use a coma to separate extensions, e.g. :
|
|
||||||
# jinja2_extensions=jinja2.ext.do,jinja2.ext.i18n
|
# jinja2_extensions=jinja2.ext.do,jinja2.ext.i18n
|
||||||
# no extensions are loaded by default
|
|
||||||
|
|
||||||
#jinja2_extensions=
|
|
||||||
|
|
||||||
# if set, always use this private key file for authentication, same as if passing
|
|
||||||
# --private-key to ansible or ansible-playbook
|
|
||||||
|
|
||||||
|
# if set, always use this private key file for authentication, same as
|
||||||
|
# if passing --private-key to ansible or ansible-playbook
|
||||||
#private_key_file=/path/to/file
|
#private_key_file=/path/to/file
|
||||||
|
|
||||||
# format of string $ansible_managed available within Jinja2 templates, replacing
|
# format of string {{ ansible_managed }} available within Jinja2
|
||||||
# {file}, {host} and {uid} with template filename, host and owner respectively.
|
# templates indicates to users editing templates files will be replaced.
|
||||||
# The resulting string is passed through strftime(3) so it may contain any
|
, replacing {file}, {host} and {uid} and strftime codes with proper values.
|
||||||
# time-formatting specifiers.
|
|
||||||
#
|
|
||||||
# Example: ansible_managed = DONT TOUCH {file}: call {uid} at {host} for changes
|
|
||||||
ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}
|
ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}
|
||||||
|
|
||||||
# additional plugin paths for non-core plugins
|
# set plugin path directories here, seperate with colons
|
||||||
|
|
||||||
action_plugins = /usr/share/ansible_plugins/action_plugins
|
action_plugins = /usr/share/ansible_plugins/action_plugins
|
||||||
callback_plugins = /usr/share/ansible_plugins/callback_plugins
|
callback_plugins = /usr/share/ansible_plugins/callback_plugins
|
||||||
connection_plugins = /usr/share/ansible_plugins/connection_plugins
|
connection_plugins = /usr/share/ansible_plugins/connection_plugins
|
||||||
|
@ -140,24 +77,23 @@ lookup_plugins = /usr/share/ansible_plugins/lookup_plugins
|
||||||
vars_plugins = /usr/share/ansible_plugins/vars_plugins
|
vars_plugins = /usr/share/ansible_plugins/vars_plugins
|
||||||
filter_plugins = /usr/share/ansible_plugins/filter_plugins
|
filter_plugins = /usr/share/ansible_plugins/filter_plugins
|
||||||
|
|
||||||
# set to 1 if you don't want cowsay support. Alternatively, set ANSIBLE_NOCOWS=1
|
# don't like cows? that's unfortunate.
|
||||||
# in your environment
|
# set to 1 if you don't want cowsay support or export ANSIBLE_NOCOWS=1
|
||||||
# nocows = 1
|
# nocows = 1
|
||||||
|
|
||||||
[paramiko_connection]
|
[paramiko_connection]
|
||||||
|
|
||||||
# nothing to configure yet
|
# nothing configurable yet
|
||||||
|
|
||||||
[ssh_connection]
|
[ssh_connection]
|
||||||
|
|
||||||
# if uncommented, sets the ansible ssh arguments to the following. Leaving off ControlPersist
|
# ssh arguments to use
|
||||||
# will result in poor performance, so use transport=paramiko on older platforms rather than
|
# Leaving off ControlPersist will result in poor performance, so use
|
||||||
# removing it
|
# paramiko on older platforms rather than removing it
|
||||||
|
|
||||||
ssh_args=-o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r
|
ssh_args=-o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r
|
||||||
|
|
||||||
# the following makes ansible use scp if the connection type is ssh (default is sftp)
|
# if True, make ansible use scp if the connection type is ssh
|
||||||
|
# (default is sftp)
|
||||||
#scp_if_ssh=True
|
#scp_if_ssh=True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,8 @@ ANSIBLE_NOCOWS = get_config(p, DEFAULTS, 'nocows', 'ANSIBLE_NOCO
|
||||||
ANSIBLE_SSH_ARGS = get_config(p, 'ssh_connection', 'ssh_args', 'ANSIBLE_SSH_ARGS', None)
|
ANSIBLE_SSH_ARGS = get_config(p, 'ssh_connection', 'ssh_args', 'ANSIBLE_SSH_ARGS', None)
|
||||||
ZEROMQ_PORT = int(get_config(p, 'fireball', 'zeromq_port', 'ANSIBLE_ZEROMQ_PORT', 5099))
|
ZEROMQ_PORT = int(get_config(p, 'fireball', 'zeromq_port', 'ANSIBLE_ZEROMQ_PORT', 5099))
|
||||||
|
|
||||||
|
DEFAULT_UNDEFINED_VAR_BEHAVIOR = get_config(p, DEFAULTS, 'error_on_undefined_vars', 'ANSIBLE_ERROR_ON_UNDEFINED_VARS', False)
|
||||||
|
|
||||||
# non-configurable things
|
# non-configurable things
|
||||||
DEFAULT_SUDO_PASS = None
|
DEFAULT_SUDO_PASS = None
|
||||||
DEFAULT_REMOTE_PASS = None
|
DEFAULT_REMOTE_PASS = None
|
||||||
|
|
|
@ -32,3 +32,6 @@ class AnsibleConnectionFailed(AnsibleError):
|
||||||
|
|
||||||
class AnsibleYAMLValidationFailed(AnsibleError):
|
class AnsibleYAMLValidationFailed(AnsibleError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class AnsibleUndefinedVariable(AnsibleError):
|
||||||
|
pass
|
||||||
|
|
|
@ -30,6 +30,7 @@ import base64
|
||||||
import sys
|
import sys
|
||||||
import shlex
|
import shlex
|
||||||
import pipes
|
import pipes
|
||||||
|
import jinja2
|
||||||
|
|
||||||
import ansible.constants as C
|
import ansible.constants as C
|
||||||
import ansible.inventory
|
import ansible.inventory
|
||||||
|
@ -128,7 +129,8 @@ class Runner(object):
|
||||||
check=False, # don't make any changes, just try to probe for potential changes
|
check=False, # don't make any changes, just try to probe for potential changes
|
||||||
diff=False, # whether to show diffs for template files that change
|
diff=False, # whether to show diffs for template files that change
|
||||||
environment=None, # environment variables (as dict) to use inside the command
|
environment=None, # environment variables (as dict) to use inside the command
|
||||||
complex_args=None # structured data in addition to module_args, must be a dict
|
complex_args=None, # structured data in addition to module_args, must be a dict
|
||||||
|
error_on_undefined_vars=C.DEFAULT_UNDEFINED_VAR_BEHAVIOR # ex. False
|
||||||
):
|
):
|
||||||
|
|
||||||
if not complex_args:
|
if not complex_args:
|
||||||
|
@ -164,6 +166,7 @@ class Runner(object):
|
||||||
self.environment = environment
|
self.environment = environment
|
||||||
self.complex_args = complex_args
|
self.complex_args = complex_args
|
||||||
self.module_with_list = False
|
self.module_with_list = False
|
||||||
|
self.error_on_undefined_vars = error_on_undefined_vars
|
||||||
|
|
||||||
self.callbacks.runner = self
|
self.callbacks.runner = self
|
||||||
|
|
||||||
|
@ -446,11 +449,11 @@ class Runner(object):
|
||||||
if type(complex_args) != dict:
|
if type(complex_args) != dict:
|
||||||
raise errors.AnsibleError("args must be a dictionary, received %s" % complex_args)
|
raise errors.AnsibleError("args must be a dictionary, received %s" % complex_args)
|
||||||
result = self._executor_internal_inner(
|
result = self._executor_internal_inner(
|
||||||
host,
|
host,
|
||||||
self.module_name,
|
self.module_name,
|
||||||
self.module_args,
|
self.module_args,
|
||||||
inject,
|
inject,
|
||||||
port,
|
port,
|
||||||
complex_args=complex_args
|
complex_args=complex_args
|
||||||
)
|
)
|
||||||
results.append(result.result)
|
results.append(result.result)
|
||||||
|
@ -576,8 +579,12 @@ class Runner(object):
|
||||||
tmp = self._make_tmp_path(conn)
|
tmp = self._make_tmp_path(conn)
|
||||||
|
|
||||||
# render module_args and complex_args templates
|
# render module_args and complex_args templates
|
||||||
module_args = template.template(self.basedir, module_args, inject)
|
try:
|
||||||
complex_args = template.template(self.basedir, complex_args, inject)
|
module_args = template.template(self.basedir, module_args, inject, fail_on_undefined=self.error_on_undefined_vars)
|
||||||
|
complex_args = template.template(self.basedir, complex_args, inject, fail_on_undefined=self.error_on_undefined_vars)
|
||||||
|
except jinja2.exceptions.UndefinedError, e:
|
||||||
|
raise errors.AnsibleUndefinedVariable("Undefined variables: %s" % str(e))
|
||||||
|
|
||||||
|
|
||||||
result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
|
result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
|
||||||
|
|
||||||
|
@ -644,7 +651,7 @@ class Runner(object):
|
||||||
path = pipes.quote(path)
|
path = pipes.quote(path)
|
||||||
# The following test needs to be SH-compliant. BASH-isms will
|
# The following test needs to be SH-compliant. BASH-isms will
|
||||||
# not work if /bin/sh points to a non-BASH shell.
|
# not work if /bin/sh points to a non-BASH shell.
|
||||||
test = "rc=0; [ -r \"%s\" ] || rc=2; [ -f \"%s\" ] || rc=1; [ -d \"%s\" ] && rc=3" % ((path,) * 3)
|
test = "rc=0; [ -r \"%s\" ] || rc=2; [ -f \"%s\" ] || rc=1; [ -d \"%s\" ] && rc=3" % ((path,) * 3)
|
||||||
md5s = [
|
md5s = [
|
||||||
"(/usr/bin/md5sum %s 2>/dev/null)" % path, # Linux
|
"(/usr/bin/md5sum %s 2>/dev/null)" % path, # Linux
|
||||||
"(/sbin/md5sum -q %s 2>/dev/null)" % path, # ?
|
"(/sbin/md5sum -q %s 2>/dev/null)" % path, # ?
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Globals(object):
|
||||||
FILTERS = None
|
FILTERS = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _get_filters():
|
def _get_filters():
|
||||||
''' return filter plugin instances '''
|
''' return filter plugin instances '''
|
||||||
|
@ -48,7 +48,7 @@ def _get_filters():
|
||||||
for fp in plugins:
|
for fp in plugins:
|
||||||
filters.update(fp.filters())
|
filters.update(fp.filters())
|
||||||
Globals.FILTERS = filters
|
Globals.FILTERS = filters
|
||||||
|
|
||||||
return Globals.FILTERS
|
return Globals.FILTERS
|
||||||
|
|
||||||
def _get_extensions():
|
def _get_extensions():
|
||||||
|
@ -90,7 +90,7 @@ def lookup(name, *args, **kwargs):
|
||||||
|
|
||||||
def _legacy_varFindLimitSpace(basedir, vars, space, part, lookup_fatal, depth, expand_lists):
|
def _legacy_varFindLimitSpace(basedir, vars, space, part, lookup_fatal, depth, expand_lists):
|
||||||
''' limits the search space of space to part
|
''' limits the search space of space to part
|
||||||
|
|
||||||
basically does space.get(part, None), but with
|
basically does space.get(part, None), but with
|
||||||
templating for part and a few more things
|
templating for part and a few more things
|
||||||
'''
|
'''
|
||||||
|
@ -295,7 +295,7 @@ def legacy_varReplace(basedir, raw, vars, lookup_fatal=True, depth=0, expand_lis
|
||||||
|
|
||||||
# TODO: varname is misnamed here
|
# TODO: varname is misnamed here
|
||||||
|
|
||||||
def template(basedir, varname, vars, lookup_fatal=True, depth=0, expand_lists=True, convert_bare=False):
|
def template(basedir, varname, vars, lookup_fatal=True, depth=0, expand_lists=True, convert_bare=False, fail_on_undefined=False):
|
||||||
''' templates a data structure by traversing it and substituting for other data structures '''
|
''' templates a data structure by traversing it and substituting for other data structures '''
|
||||||
|
|
||||||
if convert_bare and isinstance(varname, basestring):
|
if convert_bare and isinstance(varname, basestring):
|
||||||
|
@ -305,7 +305,7 @@ def template(basedir, varname, vars, lookup_fatal=True, depth=0, expand_lists=Tr
|
||||||
|
|
||||||
if isinstance(varname, basestring):
|
if isinstance(varname, basestring):
|
||||||
if '{{' in varname or '{%' in varname:
|
if '{{' in varname or '{%' in varname:
|
||||||
varname = template_from_string(basedir, varname, vars)
|
varname = template_from_string(basedir, varname, vars, fail_on_undefined)
|
||||||
if not '$' in varname:
|
if not '$' in varname:
|
||||||
return varname
|
return varname
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ class _jinja2_vars(object):
|
||||||
is avoiding duplicating the large hashes that inject tends to be.
|
is avoiding duplicating the large hashes that inject tends to be.
|
||||||
To facilitate using builtin jinja2 things like range, globals are handled
|
To facilitate using builtin jinja2 things like range, globals are handled
|
||||||
here.
|
here.
|
||||||
extras is a list of locals to also search for variables.
|
extras is a list of locals to also search for variables.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, basedir, vars, globals, *extras):
|
def __init__(self, basedir, vars, globals, *extras):
|
||||||
|
@ -398,6 +398,8 @@ class J2Template(jinja2.environment.Template):
|
||||||
def template_from_file(basedir, path, vars):
|
def template_from_file(basedir, path, vars):
|
||||||
''' run a file through the templating engine '''
|
''' run a file through the templating engine '''
|
||||||
|
|
||||||
|
fail_on_undefined = C.DEFAULT_UNDEFINED_VAR_BEHAVIOR
|
||||||
|
|
||||||
from ansible import utils
|
from ansible import utils
|
||||||
realpath = utils.path_dwim(basedir, path)
|
realpath = utils.path_dwim(basedir, path)
|
||||||
loader=jinja2.FileSystemLoader([basedir,os.path.dirname(realpath)])
|
loader=jinja2.FileSystemLoader([basedir,os.path.dirname(realpath)])
|
||||||
|
@ -409,6 +411,8 @@ def template_from_file(basedir, path, vars):
|
||||||
environment = jinja2.Environment(loader=loader, trim_blocks=True, extensions=_get_extensions())
|
environment = jinja2.Environment(loader=loader, trim_blocks=True, extensions=_get_extensions())
|
||||||
environment.filters.update(_get_filters())
|
environment.filters.update(_get_filters())
|
||||||
environment.globals['lookup'] = my_lookup
|
environment.globals['lookup'] = my_lookup
|
||||||
|
if fail_on_undefined:
|
||||||
|
environment.undefined = StrictUndefined
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = codecs.open(realpath, encoding="utf8").read()
|
data = codecs.open(realpath, encoding="utf8").read()
|
||||||
|
@ -417,7 +421,7 @@ def template_from_file(basedir, path, vars):
|
||||||
except:
|
except:
|
||||||
raise errors.AnsibleError("unable to read %s" % realpath)
|
raise errors.AnsibleError("unable to read %s" % realpath)
|
||||||
|
|
||||||
|
|
||||||
# Get jinja env overrides from template
|
# Get jinja env overrides from template
|
||||||
if data.startswith(JINJA2_OVERRIDE):
|
if data.startswith(JINJA2_OVERRIDE):
|
||||||
eol = data.find('\n')
|
eol = data.find('\n')
|
||||||
|
@ -455,15 +459,18 @@ def template_from_file(basedir, path, vars):
|
||||||
# This line performs deep Jinja2 magic that uses the _jinja2_vars object for vars
|
# This line performs deep Jinja2 magic that uses the _jinja2_vars object for vars
|
||||||
# Ideally, this could use some API where setting shared=True and the object won't get
|
# Ideally, this could use some API where setting shared=True and the object won't get
|
||||||
# passed through dict(o), but I have not found that yet.
|
# passed through dict(o), but I have not found that yet.
|
||||||
res = jinja2.utils.concat(t.root_render_func(t.new_context(_jinja2_vars(basedir, vars, t.globals), shared=True)))
|
try:
|
||||||
|
res = jinja2.utils.concat(t.root_render_func(t.new_context(_jinja2_vars(basedir, vars, t.globals), shared=True)))
|
||||||
|
except jinja2.exceptions.UndefinedError, e:
|
||||||
|
raise errors.AnsibleUndefinedVariable("Undefined variables: %s" % str(e))
|
||||||
|
|
||||||
if data.endswith('\n') and not res.endswith('\n'):
|
if data.endswith('\n') and not res.endswith('\n'):
|
||||||
res = res + '\n'
|
res = res + '\n'
|
||||||
return template(basedir, res, vars)
|
return template(basedir, res, vars)
|
||||||
|
|
||||||
def template_from_string(basedir, data, vars):
|
def template_from_string(basedir, data, vars, fail_on_undefined=False):
|
||||||
''' run a string through the (Jinja2) templating engine '''
|
''' run a string through the (Jinja2) templating engine '''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if type(data) == str:
|
if type(data) == str:
|
||||||
data = unicode(data, 'utf-8')
|
data = unicode(data, 'utf-8')
|
||||||
|
@ -487,16 +494,19 @@ def template_from_string(basedir, data, vars):
|
||||||
raise errors.AnsibleError("recursive loop detected in template string: %s" % data)
|
raise errors.AnsibleError("recursive loop detected in template string: %s" % data)
|
||||||
else:
|
else:
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def my_lookup(*args, **kwargs):
|
def my_lookup(*args, **kwargs):
|
||||||
kwargs['vars'] = vars
|
kwargs['vars'] = vars
|
||||||
return lookup(*args, basedir=basedir, **kwargs)
|
return lookup(*args, basedir=basedir, **kwargs)
|
||||||
|
|
||||||
t.globals['lookup'] = my_lookup
|
t.globals['lookup'] = my_lookup
|
||||||
|
|
||||||
res = jinja2.utils.concat(t.root_render_func(t.new_context(_jinja2_vars(basedir, vars, t.globals), shared=True)))
|
res = jinja2.utils.concat(t.root_render_func(t.new_context(_jinja2_vars(basedir, vars, t.globals), shared=True)))
|
||||||
return res
|
return res
|
||||||
except jinja2.exceptions.UndefinedError:
|
except jinja2.exceptions.UndefinedError:
|
||||||
|
if fail_on_undefined:
|
||||||
|
raise
|
||||||
|
else:
|
||||||
# this shouldn't happen due to undeclared check above
|
# this shouldn't happen due to undeclared check above
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue