diff options
author | Noah Kantrowitz <noah@coderanger.net> | 2017-04-04 12:25:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-04 12:25:42 -0700 |
commit | a22235b58c28e754d4698d9bdf27a50be6276974 (patch) | |
tree | 9ac6fb83e92e8c882a85c621e5ee69fe31fe55b5 | |
parent | f38f957878057b0609d63dc1a735819c87e3c8c9 (diff) | |
parent | bd7f7d1b07cbb19c9d08c273bc857a084ce4689b (diff) | |
download | chef-a22235b58c28e754d4698d9bdf27a50be6276974.tar.gz |
Merge pull request #6005 from coderanger/template-lazy
Allow lazy{} to be used in template resource variables.
4 files changed, 59 insertions, 1 deletions
diff --git a/lib/chef/provider/template/content.rb b/lib/chef/provider/template/content.rb index acf200621d..b40794564a 100644 --- a/lib/chef/provider/template/content.rb +++ b/lib/chef/provider/template/content.rb @@ -36,7 +36,30 @@ 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 + # If this is an Attribute object, we need to change class otherwise + # we get the immutable behavior. This could probably be fixed by + # using Hash#transform_values once we only support Ruby 2.4. + obj_class = obj.is_a?(Chef::Node::ImmutableMash) ? Mash : obj.class + # 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..b9a39255f4 100644 --- a/spec/functional/resource/template_spec.rb +++ b/spec/functional/resource/template_spec.rb @@ -32,6 +32,7 @@ describe Chef::Resource::Template do let(:node) do node = Chef::Node.new node.normal[:slappiness] = "a warm gun" + node.normal[:nested][:secret] = "value" node end @@ -209,4 +210,36 @@ 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 + + describe "when passing a node attribute mash as a template variable" do + it "uses the node attributes like a hash" do + resource.source("openldap_variable_stuff.conf.erb") + resource.variables(node[:nested]) + resource.run_action(:create) + expect(IO.read(path)).to eq("super secret is value") + end + end + end diff --git a/spec/unit/cookbook/syntax_check_spec.rb b/spec/unit/cookbook/syntax_check_spec.rb index aa6fe49eb9..a24fa3ab2a 100644 --- a/spec/unit/cookbook/syntax_check_spec.rb +++ b/spec/unit/cookbook/syntax_check_spec.rb @@ -60,6 +60,7 @@ describe Chef::Cookbook::SyntaxCheck do openldap_stuff.conf.erb nested_openldap_partials.erb nested_partial.erb + openldap_nested_variable_stuff.erb openldap_variable_stuff.conf.erb test.erb some_windows_line_endings.erb |