Brano Zarnovican
2013-Jul-15 16:25 UTC
[Puppet Users] template - need to fail if referencing undefined var
Hi, I have the following code snippet node default { # $var_a .. is undefined $var_b = hiera("var_b", undef) $var_c = undef file { "/var/tmp/foo.txt": content => inline_template(" <% if @var_a %> var_b = <%= @var_a %> <% else %> <% info(\"var_a is undefined\") %> <% end -%> <% if @var_b %> var_b = <%= @var_b %> <% else %> <% info(\"var_b is undefined\") %> <% end -%> <% if @var_c %> var_c = <%= @var_c %> <% else %> <% info(\"var_c is undefined\") %> <% end -%> " ), } } Applying it, will generate these two info messages. Info: template[inline]: var_a is undefined Info: template[inline]: var_c is undefined var_b = What I would like puppet to do is to fail if template is referencing a variable which is not defined, without having to wrap it with if-else-fail()-end. Another strange thing I''ve noticed that "undef" behaves differently if it is a default value for hiera lookup (see var_b vs var_c). Actually, my code looks more like.. $var_a = hiera("var_a") $var_b = hiera("var_b") $var_c = hiera("var_c") file {"..": content => template(hiera("tmpl_name")) } That will fail if any variable a,b,c is undefined in hiera, no matter if it is used in template or not. I can rewrite it to $var_a = hiera("var_a", undef) $var_b = hiera("var_b", undef) $var_c = hiera("var_c", undef) file {"..": content => template(hiera("tmpl_name")) } This will not fail even if variable used by the template is undefined. The value is quietly replaced by empty string. In other words, I would like to delay the failure from hiera() lookup to the time when it is actually used in template. Can it be done without explicitly testing it with "if" inside template ? Thanks, BranoZ PS: we are (or soon be) on puppet 3.2. -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users. For more options, visit https://groups.google.com/groups/opt_out.
jcbollinger
2013-Jul-17 15:29 UTC
[Puppet Users] Re: template - need to fail if referencing undefined var
On Monday, July 15, 2013 11:25:50 AM UTC-5, Brano Zarnovican wrote:> > Hi, > > I have the following code snippet > > node default { > # $var_a .. is undefined > $var_b = hiera("var_b", undef) > $var_c = undef > > file { "/var/tmp/foo.txt": content => inline_template(" > > <% if @var_a %> > var_b = <%= @var_a %> > <% else %> > <% info(\"var_a is undefined\") %> > <% end -%> > > <% if @var_b %> > var_b = <%= @var_b %> > <% else %> > <% info(\"var_b is undefined\") %> > <% end -%> > > <% if @var_c %> > var_c = <%= @var_c %> > <% else %> > <% info(\"var_c is undefined\") %> > <% end -%> > > " > ), } > } > > Applying it, will generate these two info messages. > > Info: template[inline]: var_a is undefined > Info: template[inline]: var_c is undefined > var_b = > > What I would like puppet to do is to fail if template is referencing a > variable which is not defined, without having to wrap it with > if-else-fail()-end. > > Another strange thing I''ve noticed that "undef" behaves differently if it > is a default value for hiera lookup (see var_b vs var_c). > > Actually, my code looks more like.. > > $var_a = hiera("var_a") > $var_b = hiera("var_b") > $var_c = hiera("var_c") > file {"..": content => template(hiera("tmpl_name")) } > > That will fail if any variable a,b,c is undefined in hiera, no matter if > it is used in template or not. I can rewrite it to > > $var_a = hiera("var_a", undef) > $var_b = hiera("var_b", undef) > $var_c = hiera("var_c", undef) > file {"..": content => template(hiera("tmpl_name")) } > > This will not fail even if variable used by the template is undefined. The > value is quietly replaced by empty string. > > In other words, I would like to delay the failure from hiera() lookup to > the time when it is actually used in template. Can it be done without > explicitly testing it with "if" inside template ? > > Thanks, > > BranoZ > > PS: we are (or soon be) on puppet 3.2. > >You have a couple of separate issues here, but first a little background to make sure we''re on the same page: templates are evaluated by the master, not by agents, so the only form of failure a template can exhibit is to interrupt catalog compilation with a synthetic parse error. It cannot cause application of the associated resource to fail on the agent. With that said, a template can call Puppet function via the ''scope'' object available to it. In particular, if you want a template evaluation to fail as I describe, then it can invoke the fail() function: <% scope.function_fail(''variable foo is not set'') %> Now, as a separate matter, you are correct that hiera will translate the default value ''undef'' to an empty string. It will never return an undef value (I''m not sure that even makes sense). A common approach is to instead choose a default value that you are confident will not appear as a valid value in your data. One conventional choice is ''NOTSET''. Your code then tests for that special value instead of (or in addition to) testing whether the variable is defined. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users. For more options, visit https://groups.google.com/groups/opt_out.
Spencer Krum
2013-Oct-16 17:48 UTC
[Puppet Users] Re: template - need to fail if referencing undefined var
I''ve developed the following pattern. Please don''t hate. [nibz@pdxudev01 sandbox]$ cat testpuppetfailtemplate.sh $bar = ''lies'' $derp=inline_template("<%= @bar || scope.function_fail([''die'']) %>") notify { $derp: } Which produces: [nibz@pdxudev01 sandbox]$ puppet apply testpuppetfailtemplate.sh Notice: lies Notice: /Stage[main]//Notify[lies]/message: defined ''message'' as ''lies'' Notice: Finished catalog run in 0.09 seconds Then commenting out $bar [nibz@pdxudev01 sandbox]$ puppet apply testpuppetfailtemplate.sh Error: Failed to parse inline template: die at /home/nibz/sandbox/testpuppetfailtemplate.sh:4 on node pdxudev01.devtst.go2uti.com Error: Failed to parse inline template: die at /home/nibz/sandbox/testpuppetfailtemplate.sh:4 on node pdxudev01.devtst.go2uti.com :) On Wednesday, July 17, 2013 8:29:07 AM UTC-7, jcbollinger wrote:> > > > On Monday, July 15, 2013 11:25:50 AM UTC-5, Brano Zarnovican wrote: >> >> Hi, >> >> I have the following code snippet >> >> node default { >> # $var_a .. is undefined >> $var_b = hiera("var_b", undef) >> $var_c = undef >> >> file { "/var/tmp/foo.txt": content => inline_template(" >> >> <% if @var_a %> >> var_b = <%= @var_a %> >> <% else %> >> <% info(\"var_a is undefined\") %> >> <% end -%> >> >> <% if @var_b %> >> var_b = <%= @var_b %> >> <% else %> >> <% info(\"var_b is undefined\") %> >> <% end -%> >> >> <% if @var_c %> >> var_c = <%= @var_c %> >> <% else %> >> <% info(\"var_c is undefined\") %> >> <% end -%> >> >> " >> ), } >> } >> >> Applying it, will generate these two info messages. >> >> Info: template[inline]: var_a is undefined >> Info: template[inline]: var_c is undefined >> var_b = >> >> What I would like puppet to do is to fail if template is referencing a >> variable which is not defined, without having to wrap it with >> if-else-fail()-end. >> >> Another strange thing I''ve noticed that "undef" behaves differently if it >> is a default value for hiera lookup (see var_b vs var_c). >> >> Actually, my code looks more like.. >> >> $var_a = hiera("var_a") >> $var_b = hiera("var_b") >> $var_c = hiera("var_c") >> file {"..": content => template(hiera("tmpl_name")) } >> >> That will fail if any variable a,b,c is undefined in hiera, no matter if >> it is used in template or not. I can rewrite it to >> >> $var_a = hiera("var_a", undef) >> $var_b = hiera("var_b", undef) >> $var_c = hiera("var_c", undef) >> file {"..": content => template(hiera("tmpl_name")) } >> >> This will not fail even if variable used by the template is undefined. >> The value is quietly replaced by empty string. >> >> In other words, I would like to delay the failure from hiera() lookup to >> the time when it is actually used in template. Can it be done without >> explicitly testing it with "if" inside template ? >> >> Thanks, >> >> BranoZ >> >> PS: we are (or soon be) on puppet 3.2. >> >> > > You have a couple of separate issues here, but first a little background > to make sure we''re on the same page: templates are evaluated by the master, > not by agents, so the only form of failure a template can exhibit is to > interrupt catalog compilation with a synthetic parse error. It cannot > cause application of the associated resource to fail on the agent. > > With that said, a template can call Puppet function via the ''scope'' object > available to it. In particular, if you want a template evaluation to fail > as I describe, then it can invoke the fail() function: > > <% scope.function_fail(''variable foo is not set'') %> > > > Now, as a separate matter, you are correct that hiera will translate the > default value ''undef'' to an empty string. It will never return an undef > value (I''m not sure that even makes sense). A common approach is to > instead choose a default value that you are confident will not appear as a > valid value in your data. One conventional choice is ''NOTSET''. Your code > then tests for that special value instead of (or in addition to) testing > whether the variable is defined. > > > John > >-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users. For more options, visit https://groups.google.com/groups/opt_out.
Nan Liu
2013-Oct-16 18:52 UTC
Re: [Puppet Users] Re: template - need to fail if referencing undefined var
This is essentially the behavior of stdlib pick function. $required_var = pick(hiera("var_a"), hiera("var_b")) Which could be improved to allow a custom error message: https://github.com/puppetlabs/puppetlabs-stdlib/blob/master/lib/puppet/parser/functions/pick.rb#L24 Nan On Wed, Oct 16, 2013 at 10:48 AM, Spencer Krum <krum.spencer@gmail.com>wrote:> I''ve developed the following pattern. Please don''t hate. > > [nibz@pdxudev01 sandbox]$ cat testpuppetfailtemplate.sh > > $bar = ''lies'' > > $derp=inline_template("<%= @bar || scope.function_fail([''die'']) %>") > notify { $derp: } > > Which produces: > > [nibz@pdxudev01 sandbox]$ puppet apply testpuppetfailtemplate.sh > Notice: lies > Notice: /Stage[main]//Notify[lies]/message: defined ''message'' as ''lies'' > Notice: Finished catalog run in 0.09 seconds > > Then commenting out $bar > > [nibz@pdxudev01 sandbox]$ puppet apply testpuppetfailtemplate.sh > Error: Failed to parse inline template: die at > /home/nibz/sandbox/testpuppetfailtemplate.sh:4 on node > pdxudev01.devtst.go2uti.com > Error: Failed to parse inline template: die at > /home/nibz/sandbox/testpuppetfailtemplate.sh:4 on node > pdxudev01.devtst.go2uti.com > > :) > > > > On Wednesday, July 17, 2013 8:29:07 AM UTC-7, jcbollinger wrote: >> >> >> >> On Monday, July 15, 2013 11:25:50 AM UTC-5, Brano Zarnovican wrote: >>> >>> Hi, >>> >>> I have the following code snippet >>> >>> node default { >>> # $var_a .. is undefined >>> $var_b = hiera("var_b", undef) >>> $var_c = undef >>> >>> file { "/var/tmp/foo.txt": content => inline_template(" >>> >>> <% if @var_a %> >>> var_b = <%= @var_a %> >>> <% else %> >>> <% info(\"var_a is undefined\") %> >>> <% end -%> >>> >>> <% if @var_b %> >>> var_b = <%= @var_b %> >>> <% else %> >>> <% info(\"var_b is undefined\") %> >>> <% end -%> >>> >>> <% if @var_c %> >>> var_c = <%= @var_c %> >>> <% else %> >>> <% info(\"var_c is undefined\") %> >>> <% end -%> >>> >>> " >>> ), } >>> } >>> >>> Applying it, will generate these two info messages. >>> >>> Info: template[inline]: var_a is undefined >>> Info: template[inline]: var_c is undefined >>> var_b >>> >>> What I would like puppet to do is to fail if template is referencing a >>> variable which is not defined, without having to wrap it with >>> if-else-fail()-end. >>> >>> Another strange thing I''ve noticed that "undef" behaves differently if >>> it is a default value for hiera lookup (see var_b vs var_c). >>> >>> Actually, my code looks more like.. >>> >>> $var_a = hiera("var_a") >>> $var_b = hiera("var_b") >>> $var_c = hiera("var_c") >>> file {"..": content => template(hiera("tmpl_name")) } >>> >>> That will fail if any variable a,b,c is undefined in hiera, no matter if >>> it is used in template or not. I can rewrite it to >>> >>> $var_a = hiera("var_a", undef) >>> $var_b = hiera("var_b", undef) >>> $var_c = hiera("var_c", undef) >>> file {"..": content => template(hiera("tmpl_name")) } >>> >>> This will not fail even if variable used by the template is undefined. >>> The value is quietly replaced by empty string. >>> >>> In other words, I would like to delay the failure from hiera() lookup to >>> the time when it is actually used in template. Can it be done without >>> explicitly testing it with "if" inside template ? >>> >>> Thanks, >>> >>> BranoZ >>> >>> PS: we are (or soon be) on puppet 3.2. >>> >>> >> >> You have a couple of separate issues here, but first a little background >> to make sure we''re on the same page: templates are evaluated by the master, >> not by agents, so the only form of failure a template can exhibit is to >> interrupt catalog compilation with a synthetic parse error. It cannot >> cause application of the associated resource to fail on the agent. >> >> With that said, a template can call Puppet function via the ''scope'' >> object available to it. In particular, if you want a template evaluation >> to fail as I describe, then it can invoke the fail() function: >> >> <% scope.function_fail(''variable foo is not set'') %> >> >> >> Now, as a separate matter, you are correct that hiera will translate the >> default value ''undef'' to an empty string. It will never return an undef >> value (I''m not sure that even makes sense). A common approach is to >> instead choose a default value that you are confident will not appear as a >> valid value in your data. One conventional choice is ''NOTSET''. Your code >> then tests for that special value instead of (or in addition to) testing >> whether the variable is defined. >> >> >> John >> >> -- > You received this message because you are subscribed to the Google Groups > "Puppet Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to puppet-users+unsubscribe@googlegroups.com. > To post to this group, send email to puppet-users@googlegroups.com. > Visit this group at http://groups.google.com/group/puppet-users. > For more options, visit https://groups.google.com/groups/opt_out. >-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users. For more options, visit https://groups.google.com/groups/opt_out.