@ -70,9 +70,6 @@ def _get_extensions():
return jinja_exts
return jinja_exts
class Flags :
LEGACY_TEMPLATE_WARNING = False
# TODO: refactor this file
# TODO: refactor this file
FILTER_PLUGINS = None
FILTER_PLUGINS = None
@ -97,10 +94,13 @@ def _legacy_varFindLimitSpace(basedir, vars, space, part, lookup_fatal, depth, e
templating for part and a few more things
templating for part and a few more things
DEPRECATED
DEPRECATED
LEGACY VARIABLES ARE SLATED FOR REMOVAL IN ANSIBLE 1. 6
LEGACY VARIABLES ARE SLATED FOR REMOVAL IN ANSIBLE 1. 5
use { { foo } } INSTEAD
use { { foo } } INSTEAD
'''
'''
if not C . DEFAULT_LEGACY_PLAYBOOK_VARIABLES :
raise Exception ( " we should not be here " )
# Previous part couldn't be found, nothing to limit to
# Previous part couldn't be found, nothing to limit to
if space is None :
if space is None :
return space
return space
@ -153,14 +153,14 @@ def _legacy_varFind(basedir, text, vars, lookup_fatal, depth, expand_lists):
original data in the caller .
original data in the caller .
DEPRECATED
DEPRECATED
LEGACY VARIABLES ARE SLATED FOR REMOVAL IN ANSIBLE 1. 6
LEGACY VARIABLES ARE SLATED FOR REMOVAL IN ANSIBLE 1. 5
use { { foo } } INSTEAD
use { { foo } } INSTEAD
'''
'''
# short circuit this whole function if we have specified we don't want
# short circuit this whole function if we have specified we don't want
# legacy var replacement
# legacy var replacement
if C . DEFAULT_LEGACY_PLAYBOOK_VARIABLES == False :
if not C . DEFAULT_LEGACY_PLAYBOOK_VARIABLES :
r eturn None
r aise Exception ( " we should not be here " )
start = text . find ( " $ " )
start = text . find ( " $ " )
if start == - 1 :
if start == - 1 :
@ -271,10 +271,13 @@ def legacy_varReplace(basedir, raw, vars, lookup_fatal=True, depth=0, expand_lis
''' Perform variable replacement of $variables in string raw using vars dictionary
''' Perform variable replacement of $variables in string raw using vars dictionary
DEPRECATED
DEPRECATED
LEGACY VARIABLES ARE SLATED FOR REMOVAL IN ANSIBLE 1. 6
LEGACY VARIABLES ARE SLATED FOR REMOVAL IN ANSIBLE 1. 5
use { { foo } } INSTEAD
use { { foo } } INSTEAD
'''
'''
if not C . DEFAULT_LEGACY_PLAYBOOK_VARIABLES :
raise Exception ( " we should not be here " )
# this code originally from yum (and later modified a lot)
# this code originally from yum (and later modified a lot)
orig = raw
orig = raw
@ -313,17 +316,26 @@ def legacy_varReplace(basedir, raw, vars, lookup_fatal=True, depth=0, expand_lis
if result != orig :
if result != orig :
from ansible import utils
from ansible import utils
utils . deprecated ( " Legacy variable subsitution, such as using $ {foo} or $foo instead of {{ foo }} is currently valid but will be phased out and has been out of favor since version 1.2. This is the last of legacy features on our deprecation list. You may continue to use this if you have specific needs for now " , " 1. 6 " )
utils . deprecated ( " Legacy variable subsitution, such as using $ {foo} or $foo instead of {{ foo }} is currently valid but will be phased out and has been out of favor since version 1.2. This is the last of legacy features on our deprecation list. You may continue to use this if you have specific needs for now " , " 1. 5 " )
return result
return result
def template ( basedir , input_value , vars , lookup_fatal = True , depth = - 1 , expand_lists = True , convert_bare = False ):
def template ( basedir , input_value , vars , lookup_fatal = True , depth = - 1 , expand_lists = True , convert_bare = False , fail_on_undefined = False , filter_fatal = True ):
last_time = input_value
last_time = input_value
result = None
result = None
changed = True
changed = True
while changed :
while changed :
result = _template (
result = _template (
basedir , last_time , vars , lookup_fatal = lookup_fatal , depth = depth , expand_lists = expand_lists , convert_bare = convert_bare )
basedir ,
last_time ,
vars ,
lookup_fatal = lookup_fatal ,
depth = depth ,
expand_lists = expand_lists ,
convert_bare = convert_bare ,
fail_on_undefined = fail_on_undefined ,
filter_fatal = filter_fatal ,
)
if last_time != result :
if last_time != result :
changed = True
changed = True
else :
else :
@ -334,7 +346,7 @@ def template(basedir, input_value, vars, lookup_fatal=True, depth=-1, expand_lis
raise errors . AnsibleError ( " template recursion depth exceeded " )
raise errors . AnsibleError ( " template recursion depth exceeded " )
return result
return result
def template( basedir , varname , vars , lookup_fatal = True , depth = 0 , expand_lists = True , convert_bare = False , fail_on_undefined = False , filter_fatal = True ) :
def _ template( basedir , varname , vars , lookup_fatal = True , depth = 0 , expand_lists = True , convert_bare = False , fail_on_undefined = False , filter_fatal = True ) :
''' 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 '''
try :
try :
@ -346,24 +358,25 @@ 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 , fail_on_undefined )
varname = template_from_string ( basedir , varname , vars , fail_on_undefined )
if not ' $ ' in varname :
if not C . DEFAULT_LEGACY_PLAYBOOK_VARIABLES :
return varname
return varname
if not ' $ ' in varname :
return varname
m = _legacy_varFind ( basedir , varname , vars , lookup_fatal , depth , expand_lists )
m = _legacy_varFind ( basedir , varname , vars , lookup_fatal , depth , expand_lists )
if not m :
if not m :
return varname
return varname
if m [ ' start ' ] == 0 and m [ ' end ' ] == len ( varname ) :
if m [ ' start ' ] == 0 and m [ ' end ' ] == len ( varname ) :
if m [ ' replacement ' ] is not None :
if m [ ' replacement ' ] is not None :
Flags . LEGACY_TEMPLATE_WARNING = True
return template ( basedir , m [ ' replacement ' ] , vars , lookup_fatal , depth , expand_lists )
return template ( basedir , m [ ' replacement ' ] , vars , lookup_fatal , depth , expand_lists )
else :
else :
return varname
return varname
else :
else :
Flags . LEGACY_TEMPLATE_WARNING = True
return legacy_varReplace ( basedir , varname , vars , lookup_fatal , depth , expand_lists )
return legacy_varReplace ( basedir , varname , vars , lookup_fatal , depth , expand_lists )
elif isinstance ( varname , ( list , tuple ) ) :
elif isinstance ( varname , ( list , tuple ) ) :
return [ template ( basedir , v , vars , lookup_fatal , depth , expand_lists , fail_on_undefined = fail_on_undefined ) for v in varname ]
return [ template ( basedir , v , vars , lookup_fatal , depth , expand_lists , fail_on_undefined = fail_on_undefined ) for v in varname ]
elif isinstance ( varname , dict ) :
elif isinstance ( varname , dict ) :
d = { }
d = { }
for ( k , v ) in varname . iteritems ( ) :
for ( k , v ) in varname . iteritems ( ) :
@ -371,6 +384,7 @@ def template(basedir, varname, vars, lookup_fatal=True, depth=0, expand_lists=Tr
return d
return d
else :
else :
return varname
return varname
except errors . AnsibleFilterError :
except errors . AnsibleFilterError :
if filter_fatal :
if filter_fatal :
raise
raise
@ -394,7 +408,6 @@ def template_from_file(basedir, path, vars):
environment . filters . update ( _get_filters ( ) )
environment . filters . update ( _get_filters ( ) )
environment . globals [ ' lookup ' ] = my_lookup
environment . globals [ ' lookup ' ] = my_lookup
if fail_on_undefined :
if fail_on_undefined :
print " DEBUG: fail on undefined is engaged "
environment . undefined = StrictUndefined
environment . undefined = StrictUndefined
try :
try :
@ -414,7 +427,6 @@ def template_from_file(basedir, path, vars):
( key , val ) = pair . split ( ' : ' )
( key , val ) = pair . split ( ' : ' )
setattr ( environment , key . strip ( ) , ast . literal_eval ( val . strip ( ) ) )
setattr ( environment , key . strip ( ) , ast . literal_eval ( val . strip ( ) ) )
t = environment . from_string ( data )
vars = vars . copy ( )
vars = vars . copy ( )
try :
try :
template_uid = pwd . getpwuid ( os . stat ( realpath ) . st_uid ) . pw_name
template_uid = pwd . getpwuid ( os . stat ( realpath ) . st_uid ) . pw_name
@ -439,9 +451,16 @@ def template_from_file(basedir, path, vars):
)
)
try :
try :
t = environment . from_string ( data )
res = t . render ( vars )
res = t . render ( vars )
except jinja2 . exceptions . UndefinedError , e :
except jinja2 . exceptions . UndefinedError , e :
raise errors . AnsibleUndefinedVariable ( " One or more undefined variables: %s " % str ( e ) )
raise errors . AnsibleUndefinedVariable ( " One or more undefined variables: %s " % str ( e ) )
except TemplateSyntaxError , e :
# Throw an exception which includes a more user friendly error message
values = dict ( name = realpath , lineno = e . lineno , error = str ( e ) )
msg = ' file: %(name)s , line number: %(lineno)s , error: %(error)s ' % values
error = errors . AnsibleError ( msg )
raise error
if data . endswith ( ' \n ' ) and not res . endswith ( ' \n ' ) :
if data . endswith ( ' \n ' ) and not res . endswith ( ' \n ' ) :
res = res + ' \n '
res = res + ' \n '
@ -450,13 +469,14 @@ def template_from_file(basedir, path, vars):
def template_from_string ( basedir , data , vars , fail_on_undefined = False ) :
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 '''
def my_lookup ( * args , * * kwargs ) :
kwargs [ ' vars ' ] = vars
return lookup ( * args , basedir = basedir , * * kwargs )
if type ( data ) == str :
if type ( data ) == str :
data = unicode ( data , ' utf-8 ' )
data = unicode ( data , ' utf-8 ' )
environment = jinja2 . Environment ( trim_blocks = True , undefined = StrictUndefined , extensions = _get_extensions ( ) )
environment = jinja2 . Environment ( trim_blocks = True , undefined = StrictUndefined , extensions = _get_extensions ( ) )
environment . filters . update ( _get_filters ( ) )
environment . filters . update ( _get_filters ( ) )
if fail_on_undefined :
print " DEBUG: fail on undefined is engaged, 2 "
environment . undefined = StrictUndefined
if ' _original_file ' in vars :
if ' _original_file ' in vars :
basedir = os . path . dirname ( vars [ ' _original_file ' ] )
basedir = os . path . dirname ( vars [ ' _original_file ' ] )
@ -467,6 +487,21 @@ def template_from_string(basedir, data, vars, fail_on_undefined=False):
# TODO: may need some way of using lookup plugins here seeing we aren't calling
# TODO: may need some way of using lookup plugins here seeing we aren't calling
# the legacy engine, lookup() as a function, perhaps?
# the legacy engine, lookup() as a function, perhaps?
if type ( data ) == str :
data = unicode ( data , ' utf-8 ' )
environment = jinja2 . Environment ( trim_blocks = True , undefined = StrictUndefined , extensions = _get_extensions ( ) )
environment . filters . update ( _get_filters ( ) )
if ' _original_file ' in vars :
basedir = os . path . dirname ( vars [ ' _original_file ' ] )
filesdir = os . path . abspath ( os . path . join ( basedir , ' .. ' , ' files ' ) )
if os . path . exists ( filesdir ) :
basedir = filesdir
# TODO: may need some way of using lookup plugins here seeing we aren't calling
# the legacy engine, lookup() as a function, perhaps?
data = data . decode ( ' utf-8 ' )
try :
try :
t = environment . from_string ( data )
t = environment . from_string ( data )
except Exception , e :
except Exception , e :
@ -475,19 +510,11 @@ def template_from_string(basedir, data, vars, fail_on_undefined=False):
else :
else :
return data
return data
def my_lookup ( * args , * * kwargs ) :
kwargs [ ' vars ' ] = vars
return lookup ( * args , basedir = basedir , * * kwargs )
t . globals [ ' lookup ' ] = my_lookup
try :
try :
return t . render ( vars )
return t . render ( vars )
except jinja2 . exceptions . UndefinedError :
except jinja2 . exceptions . UndefinedError :
if fail_on_undefined :
if fail_on_undefined :
raise
raise
else :
else :
# this shouldn't happen due to undeclared check above
return data
return data