diff options
4 files changed, 112 insertions, 0 deletions
| diff --git a/puppet/modules/templatewlv/Modulefile b/puppet/modules/templatewlv/Modulefile new file mode 100644 index 00000000..8007a070 --- /dev/null +++ b/puppet/modules/templatewlv/Modulefile @@ -0,0 +1,11 @@ +name    'duritong-templatewlv' +version '0.0.1' +source 'https://github.com/duritong/puppet-templatewlv.git' +author 'duritong' +license 'Apache License, Version 2.0' +summary 'Template With Local Variables' +description 'Pass local variables to templates' +project_page 'https://github.com/duritong/puppet-templatewlv' + +## Add dependencies, if any: +# dependency 'username/name', '>= 1.2.0' diff --git a/puppet/modules/templatewlv/README.md b/puppet/modules/templatewlv/README.md new file mode 100644 index 00000000..5ab01e45 --- /dev/null +++ b/puppet/modules/templatewlv/README.md @@ -0,0 +1,21 @@ +# templatewlv + +## Template With Local Variables + +A wrapper around puppet's template function. See +[the templating docs](http://docs.puppetlabs.com/guides/templating.html) for  +the basic functionality. + +Additionally, you can pass a hash, as the last argument, which will be turned into +local variables and available to the template itself. This will allow you  to define +variables in a template and pass them down to a template you include in the current +template. An example: + +    scope.function_templatewlv(['sub_template', { 'local_var' => 'value' }]) +   +Note that if multiple templates are specified, their output is all +concatenated and returned as the output of the function. + +# Who - License + +duritong - Apache License, Version 2.0 diff --git a/puppet/modules/templatewlv/lib/puppet/parser/functions/templatewlv.rb b/puppet/modules/templatewlv/lib/puppet/parser/functions/templatewlv.rb new file mode 100644 index 00000000..c9579e2c --- /dev/null +++ b/puppet/modules/templatewlv/lib/puppet/parser/functions/templatewlv.rb @@ -0,0 +1,41 @@ +require File.join(File.dirname(__FILE__),'../templatewrapperwlv') +Puppet::Parser::Functions::newfunction(:templatewlv, :type => :rvalue, :arity => -2, :doc => +  "A wrapper around puppet's template function. See +  [the templating docs](http://docs.puppetlabs.com/guides/templating.html) for  +  the basic functionality. + +  Additionally, you can pass a hash, as the last argument, which will be turned into +  local variables and available to the template itself. This will allow you  to define +  variables in a template and pass them down to a template you include in the current +  template. An example: + +    scope.function_templatewlv(['sub_template', { 'local_var' => 'value' }]) +   +  Note that if multiple templates are specified, their output is all +  concatenated and returned as the output of the function.") do |vals| + +    if vals.last.is_a?(Hash) +      local_vars = vals.last +      local_vals = vals[0..-2] +    else +      local_vars = {} +      local_vals = vals +    end + +    result = nil +    local_vals.collect do |file| +      # Use a wrapper, so the template can't get access to the full +      # Scope object. +      debug "Retrieving template #{file}" + +      wrapper = Puppet::Parser::TemplateWrapperWlv.new(self,local_vars) +      wrapper.file = file +      begin +        wrapper.result +      rescue => detail +        info = detail.backtrace.first.split(':') +        raise Puppet::ParseError, +          "Failed to parse template #{file}:\n  Filepath: #{info[0]}\n  Line: #{info[1]}\n  Detail: #{detail}\n" +      end +    end.join("") +end diff --git a/puppet/modules/templatewlv/lib/puppet/parser/templatewrapperwlv.rb b/puppet/modules/templatewlv/lib/puppet/parser/templatewrapperwlv.rb new file mode 100644 index 00000000..f1753e18 --- /dev/null +++ b/puppet/modules/templatewlv/lib/puppet/parser/templatewrapperwlv.rb @@ -0,0 +1,39 @@ +# A wrapper for templates, that allows you to additionally define +# local variables +class Puppet::Parser::TemplateWrapperWlv < Puppet::Parser::TemplateWrapper +  attr_reader :local_vars +  def initialize(scope, local_vars) +    super(scope) +    @local_vars = local_vars +  end + +  # Should return true if a variable is defined, false if it is not +  def has_variable?(name) +    super(name) || local_vars.keys.include?(name.to_s) +  end + +  def method_missing(name, *args) +    if local_vars.keys.include?(n=name.to_s) +      local_vars[n] +    else +      super(name, *args) +    end +  end + +  def result(string = nil) +    # Expose all the variables in our scope as instance variables of the +    # current object, making it possible to access them without conflict +    # to the regular methods. +    benchmark(:debug, "Bound local template variables for #{@__file__}") do +      local_vars.each do |name, value| +        if name.kind_of?(String) +          realname = name.gsub(/[^\w]/, "_") +        else +          realname = name +        end +        instance_variable_set("@#{realname}", value) +      end +    end +    super(string) +  end +end | 
