This mostly looks good, but what happens if you specify parameters for a
parameterized class both in your manifest and in the ENC script? From our
testing, it looks like the ENC parameters are just ignored. This is in
contrast to specifying ordinary variables/parameters, in which case there is
an error about redefining the variable. What is the correct behavior in this
case? For instance,
site.pp:
class foo($x) {
notify { "x is $x": }
}
class { foo:
x => "bar",
}
output from ENC script:
---
name: localhost.localdomain
parameters: {}
classes:
x: baz
Currently, this prints "x is bar", but it seems to me like it should
probably give a duplicate definition error.
On Mon, Jan 3, 2011 at 2:17 PM, Dan Bode <[email protected]> wrote:
> Sorry for the double post.
>
> Anyways, some missing notes from the patch submission.
>
> First of all, the unit tests are clearly lacking, I wanted to hurry up and
> get the source code out for review, and will continue to work on more robust
> unit tests.
>
> I ran the following manual tests using Puppet (I would like to get unit
> test coverages for these tests, but it seems daunting):
>
> 1. should be able to pass valid attributes - passed
> 2. fails if required attributes are not passed - passed
> 3. fails is invalid attributes are passed - passed
> 4. allows multiple classes to be specified - passed
> 5. works with class namespaces - passed
> 6. attributes are not required for classes - passed
> 7. can set stages? I can set the main stage without error, but I cannot
> create stages
> 8. can set meta-param:
> - I can set tags - passed
> - could not set noop - did not work?
> - can I set dependencies on other classes from ENC? - NO
> - can I set dependencies on resources not in the ENC? - NO
> 10. fails if out parent class is missing attributes - passes
> 11. class with parent with parameters - success (order does not matter)
> 12. set classes with top scope variables (using dynamic scoping) - success
> 13. are tags applied correctly? - they seem to be
> 14. order of specifying parents and children should not matter - passed
>
> other considerations for the future:
> - maybe we should be able to specify stages
> - should be able to use params from parameters:
>
> usage example:
>
> parameters:
> fooarray: encfooarray
> foo: top
> classes:
> foo:
> bar: blaz
> baz: 'dudE'
> blah::foo:
> blah:
> blah::parent:
> needed: foo
>
> -Dan
>
>
> On Mon, Jan 3, 2011 at 1:39 PM, Dan Bode <[email protected]> wrote:
>
>> This experimental patch is intended to add support for param classes
>> to the ENC.
>>
>> The patch does the following:
>> 1. adds the ability to accept attributes to ensure_in_catalog
>> 2. added hash support for a node's classes to accept a hash
>>
>> Signed-off-by: Dan Bode <[email protected]>
>> ---
>> lib/puppet/parser/compiler.rb | 17 ++++++++++++++++-
>> lib/puppet/resource/type.rb | 5 ++++-
>> spec/unit/parser/compiler_spec.rb | 22 ++++++++++++++++++++++
>> 3 files changed, 42 insertions(+), 2 deletions(-)
>>
>> diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb
>> index c60e1d4..e29bdd7 100644
>> --- a/lib/puppet/parser/compiler.rb
>> +++ b/lib/puppet/parser/compiler.rb
>> @@ -129,6 +129,17 @@ class Puppet::Parser::Compiler
>>
>> # Evaluate all of the classes specified by the node.
>> def evaluate_node_classes
>> + if @node.classes.class == Hash
>> + @node.classes.each do |name, params|
>> + params ||= {}
>> + # I have to find the hostclass
>> + if klass = topscope.find_hostclass(name)
>> + #resource = Puppet::Resource::Type.new(:hostclass, name)
>> + klass.ensure_in_catalog(topscope, params)
>> + end
>> + end
>> + @node.classes = @node.classes.keys
>> + end
>> evaluate_classes(@node.classes, topscope)
>> end
>>
>> @@ -432,7 +443,11 @@ class Puppet::Parser::Compiler
>> @resources = []
>>
>> # Make sure any external node classes are in our class list
>> - @catalog.add_class(*[email protected])
>> + if @node.classes.class == Hash
>> + @catalog.add_class(*[email protected])
>> + else
>> + @catalog.add_class(*[email protected])
>> + end
>> end
>>
>> # Set the node's parameters into the top-scope as variables.
>> diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb
>> index d40adc1..80d1133 100644
>> --- a/lib/puppet/resource/type.rb
>> +++ b/lib/puppet/resource/type.rb
>> @@ -143,7 +143,7 @@ class Puppet::Resource::Type
>> # classes and nodes. No parameters are be supplied--if this is a
>> # parameterized class, then all parameters take on their default
>> # values.
>> - def ensure_in_catalog(scope)
>> + def ensure_in_catalog(scope, attributes={})
>> type == :definition and raise ArgumentError, "Cannot create resources
>> for defined resource types"
>> resource_type = type == :hostclass ? :class : :node
>>
>> @@ -155,6 +155,9 @@ class Puppet::Resource::Type
>> end
>>
>> resource = Puppet::Parser::Resource.new(resource_type, name, :scope =>
>> scope, :source => self)
>> + attributes.each do |k,v|
>> + resource.set_parameter(k,v)
>> + end
>> instantiate_resource(scope, resource)
>> scope.compiler.add_resource(scope, resource)
>> resource
>> diff --git a/spec/unit/parser/compiler_spec.rb
>> b/spec/unit/parser/compiler_spec.rb
>> index 95f3853..f569328 100755
>> --- a/spec/unit/parser/compiler_spec.rb
>> +++ b/spec/unit/parser/compiler_spec.rb
>> @@ -109,6 +109,16 @@ describe Puppet::Parser::Compiler do
>> compiler.classlist.should include("bar")
>> end
>>
>> + it "should transform node class hashes into a class list" do
>> + node = Puppet::Node.new("mynode")
>> + @node.classes = {'foo'=>{'one'=>'1'}, 'bar'=>{'two'=>'2'}}
>> + node.classes = {'foo'=>{'one'=>'1'}, 'bar'=>{'two'=>'2'}}
>> + compiler = Puppet::Parser::Compiler.new(node)
>> +
>> + compiler.classlist.should include("foo")
>> + compiler.classlist.should include("bar")
>> + end
>> +
>> it "should add a 'main' stage to the catalog" do
>> @compiler.catalog.resource(:stage, :main).should
>> be_instance_of(Puppet::Parser::Resource)
>> end
>> @@ -185,6 +195,18 @@ describe Puppet::Parser::Compiler do
>> @compiler.class.publicize_methods(:evaluate_node_classes) {
>> @compiler.evaluate_node_classes }
>> end
>>
>> + it "should evaluate any parameterized classes named in the node" do
>> + classes = {'foo'=>{'one'=>'1'}, 'bar'=>{'two'=>'2'}}
>> + main = stub 'main'
>> + one = stub 'one', :name => "one"
>> + three = stub 'three', :name => "three"
>> + @node.stubs(:name).returns("whatever")
>> + @node.stubs(:classes).returns(classes)
>> +
>> + @compiler.expects(:evaluate_classes).with(classes,
>> @compiler.topscope)
>> + @compiler.class.publicize_methods(:evaluate_node_classes) {
>> @compiler.evaluate_node_classes }
>> + end
>> +
>> it "should evaluate the main class if it exists" do
>> compile_stub(:evaluate_main)
>> main_class = @known_resource_types.add
>> Puppet::Resource::Type.new(:hostclass, "")
>> --
>> 1.5.5.6
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Puppet Developers" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to
>> [email protected]<puppet-dev%[email protected]>
>> .
>> For more options, visit this group at
>> http://groups.google.com/group/puppet-dev?hl=en.
>>
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Puppet Developers" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<puppet-dev%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/puppet-dev?hl=en.
>
--
You received this message because you are subscribed to the Google Groups
"Puppet Developers" 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-dev?hl=en.