Issue #13567 has been updated by Reid Vandewiele.

Branch set to https://github.com/puppetlabs/puppet/pull/617

Pull request submitted on Github: 
[https://github.com/puppetlabs/puppet/pull/617](https://github.com/puppetlabs/puppet/pull/617)
----------------------------------------
Bug #13567: create_resources pseudo-randomly overrides provided :name parameters
https://projects.puppetlabs.com/issues/13567#change-59075

Author: Reid Vandewiele
Status: Unreviewed
Priority: Normal
Assignee: 
Category: functions
Target version: 
Affected Puppet version: 
Keywords: create_resources
Branch: https://github.com/puppetlabs/puppet/pull/617


## Bug Description

The create_resources function as defined will inconsistently override provided 
:name parameters. The expected behavior is that if a name parameter is passed 
in by the user, that user-provided name parameter will be used to declare the 
resource.

The problem is in 
[lib/puppet/parser/functions/create_resources:61](https://github.com/puppetlabs/puppet/blob/c560f7150972a507ad5b2a4dc6412be8b83e94a9/lib/puppet/parser/functions/create_resources.rb#L61):

            # for a defined type.
            when :type, :define
              p_resource = Puppet::Parser::Resource.new(type_name, title, 
:scope => self, :source => resource)
    61 -->    params.merge(:name => title).each do |k,v|
                p_resource.set_parameter(k,v)
              end
              if type_of_resource == :define then

The assumption being made here is that the :name parameter is not being 
provided, and should be set to :title. Furthermore, the assumption is being 
made that hash key-value pairs passed to create_resources will have the type 
String => String.

If a :name parameter is provided, one of two things will occur.

* If the parameter has been passed via a puppet DSL hash, json, or through yaml 
without an explicit key cast to symbol, its representation in the params hash 
will be a key-value pair of type String => String. This means that after the 
merge, params will contain both `{:name => title}` and `{"name" => 
"user_value"}`. Because Hash.each ordering is effectively non-deterministic, 
whether the resource will be declared with the name `title` or `user_value` is 
undefined and will vary between runs.
* If the parameter has been passed via yaml and the key explicitly cast to 
symbol, the merge operation will strip away the user-provided :name value and 
the name of the created resource will be set to title.

## Bug Demonstration

The problem can be demonstrated using the notify resource and taking advantage 
of the fact that the message parameter defaults to the value of the name 
parameter.

    [marut@kestrel:~] % for i in {1..5}
    > do
    > echo run $i
    > puppet apply --exec 'create_resources(notify, { "title" => { name => 
"user_value" } })'
    > done
    run 1 
    notice: title
    notice: /Stage[main]//Notify[title]/message: defined 'message' as 'title'
    notice: Finished catalog run in 0.02 seconds
    run 2 
    notice: title
    notice: /Stage[main]//Notify[title]/message: defined 'message' as 'title'
    notice: Finished catalog run in 0.02 seconds
    run 3 
    notice: user_value
    notice: /Stage[main]//Notify[title]/message: defined 'message' as 
'user_value'
    notice: Finished catalog run in 0.02 seconds
    run 4 
    notice: user_value
    notice: /Stage[main]//Notify[title]/message: defined 'message' as 
'user_value'
    notice: Finished catalog run in 0.02 seconds
    run 5 
    notice: title
    notice: /Stage[main]//Notify[title]/message: defined 'message' as 'title'
    notice: Finished catalog run in 0.02 seconds
    [marut@kestrel:~] % 

Note how the value of the name/message parameter is not consistent or 
predictable between runs.

## Suggested solution

1. Before working with params, convert all keys in params to symbols.
2. Reverse the order of the merge operation on line 61 so that if a 
user-provided :name parameter exists, it will be used instead of title.


-- 
You have received this notification because you have either subscribed to it, 
or are involved in it.
To change your notification preferences, please click here: 
http://projects.puppetlabs.com/my/account

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Bugs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-bugs?hl=en.

Reply via email to