diff options
-rw-r--r-- | lib/chef/provider/template/content.rb | 21 | ||||
-rw-r--r-- | spec/data/cookbooks/openldap/templates/default/openldap_nested_variable_stuff.erb | 1 | ||||
-rw-r--r-- | spec/functional/resource/template_spec.rb | 23 |
3 files changed, 44 insertions, 1 deletions
diff --git a/lib/chef/provider/template/content.rb b/lib/chef/provider/template/content.rb index acf200621d..e47bbd4a7c 100644 --- a/lib/chef/provider/template/content.rb +++ b/lib/chef/provider/template/content.rb @@ -36,7 +36,26 @@ class Chef private def file_for_provider - context = TemplateContext.new(new_resource.variables) + # Deal with any DelayedEvaluator values in the template variables. + visitor = lambda do |obj| + case obj + when Hash + # Avoid mutating hashes in the resource in case we're changing anything. + obj.each_with_object(obj.class.new) do |(key, value), memo| + memo[key] = visitor.call(value) + end + when Array + # Avoid mutating arrays in the resource in case we're changing anything. + obj.map {|value| visitor.call(value) } + when DelayedEvaluator + new_resource.instance_eval(&obj) + else + obj + end + end + variables = visitor.call(new_resource.variables) + + context = TemplateContext.new(variables) context[:node] = run_context.node context[:template_finder] = template_finder diff --git a/spec/data/cookbooks/openldap/templates/default/openldap_nested_variable_stuff.erb b/spec/data/cookbooks/openldap/templates/default/openldap_nested_variable_stuff.erb new file mode 100644 index 0000000000..5ebee33806 --- /dev/null +++ b/spec/data/cookbooks/openldap/templates/default/openldap_nested_variable_stuff.erb @@ -0,0 +1 @@ +super secret is <%= @secret.first["key"] -%> diff --git a/spec/functional/resource/template_spec.rb b/spec/functional/resource/template_spec.rb index 32529fbb0c..7f23528821 100644 --- a/spec/functional/resource/template_spec.rb +++ b/spec/functional/resource/template_spec.rb @@ -209,4 +209,27 @@ describe Chef::Resource::Template do end end + describe "when template variables contain lazy{} calls" do + it "resolves the DelayedEvaluator" do + resource.source("openldap_variable_stuff.conf.erb") + resource.variables(:secret => Chef::DelayedEvaluator.new { "nutella" }) + resource.run_action(:create) + expect(IO.read(path)).to eq("super secret is nutella") + end + + it "does not mutate the resource variables" do + resource.source("openldap_variable_stuff.conf.erb") + resource.variables(:secret => Chef::DelayedEvaluator.new { "nutella" }) + resource.run_action(:create) + expect(resource.variables[:secret]).to be_a Chef::DelayedEvaluator + end + + it "resolves the DelayedEvaluator when deeply nested" do + resource.source("openldap_nested_variable_stuff.erb") + resource.variables(:secret => [{"key" => Chef::DelayedEvaluator.new { "nutella" }}]) + resource.run_action(:create) + expect(IO.read(path)).to eq("super secret is nutella") + end + end + end |