So, found another wrinkle in this:
If the resource doesn't exist on the system yet, and I leave the servers
attribute out, my validate doesn't catch it:
mytype{'test type':
# servers => ['server1','server2']
}
That should fail the catalog compile since servers is required and it isn't
set. My validate code looks like:
validate do
if(self[:servers])
fail("Servers must be an array with at least one member") unless
self[:servers].is_a?(Array) and self[:servers].size > 0
end
end
I found out that isrequired in the newproperty block doesn't actually do
anything, so I need some way to detect that the resource doesn't exist yet,
but the catalog specified by the user is wrong.
On Tuesday, August 11, 2015 at 3:35:13 PM UTC-4, [email protected] wrote:
>
> Okay, so if I understand you right, validate gets called twice: once
> without the self hash initialized and once with it initialized. Seems
> weird, but I can follow that. So, I might want to do something like:
>
> if(self[:servers])
> fail("Servers must be an array with at least one member") unless
> self[:servers].is_a?(Array) and self[:servers].size > 0
> end
>
> Here's a follow-up then: how can you tell the difference between self
> just not being initialized and the user failing to specify the value for a
> particular property? I guess I'm mitigating it somewhat by doing:
>
> newproperty(:servers,:array_matching=>:all) do
> desc "List of database servers; first server in the list will be
> considered the primary server"
>
> * isrequired*
> def insync?(is)
> return false unless is == should
> true
> end
>
> end
>
> And properties that aren't required wouldn't need to differentiate between
> not being set and just not initialized yet.
>
> On Tuesday, August 11, 2015 at 2:27:06 PM UTC-4, Hunter Haugen wrote:
>>
>>
>>
>> On Fri, Aug 7, 2015 at 1:48 PM <[email protected]> wrote:
>>
>>> Hi all!
>>>
>>> I'm having trouble with a custom type's type-wide validate call. I've
>>> done a lot of digging into the Puppet documentation and a lot of Googling
>>> and haven't found a lot of guidance. My Puppet version is 3.7.5.
>>>
>>> Basically, I have a property defined like this in my type:
>>>
>>> newproperty(:servers,:array_matching=>:all) do
>>> desc "List of database servers; first server in the list will be
>>> considered the primary server"
>>>
>>> isrequired
>>> def insync?(is)
>>> return false unless is == should
>>> true
>>> end
>>>
>>> end
>>>
>>> I want to check that the array is non-empty. I figured out if I
>>> specify a validate block inside of the newproperty block then I'll just get
>>> each individual array member, one at a time, which isn't what I want. So,
>>> instead, I implemented a type-wide validate call like this:
>>>
>>> Puppet::Type.newtype(:my_type) do
>>>
>>> validate do
>>> fail("servers should have at least one member") if
>>> self[:servers].size == 0
>>> done
>>>
>>
>> It's kind of awkward, but if your type uses self.instances, then in the
>> validate block is run after self.instances runs and has
>> resource.provider.servers but not self[:servers]. So I usually just do
>> something like `if self[:servers] and self[:servers].size == 0` to avoid
>> validating self.instances stuff.
>>
>> The validate block is then run again when each resource is evaluated, and
>> that is when self's hash is populated with values from the catalog.
>>
>>>
>>>
>>> When I try to run puppet resource my_type, I get:
>>>
>>> Error: Could not run: undefined method `size' for nil:NilClass
>>>
>>> When I do a pp on self, I get something that looks like (in part):
>>>
>>> #<Puppet::Type::My_type:0x000000035f7528
>>> @managed=false,
>>> @name_var_cache=:name,
>>> @original_parameters=
>>> {:provider=>
>>> #<Puppet::Type::My_type::ProviderMy_type:0x000000035d1350
>>> @property_flush={},
>>> @property_hash=
>>> {
>>> :servers=>["db1"],
>>> },
>>> @resource=#<Puppet::Type::My_type:0x000000035f7528 ...>>},
>>> @parameters=
>>> {
>>> *snip*
>>> },
>>> @provider=
>>> #<Puppet::Type::My_type::ProviderMy_type:0x000000035d1350
>>> @property_flush={},
>>> @property_hash=
>>> {
>>> :servers=>["db1"],
>>> },
>>> @resource=#<Puppet::Type::My_type:0x000000035f7528 ...>>,
>>> @tags=
>>> #<Puppet::Util::TagSet: {"my_type",
>>> "mytitle"}>,
>>> @title="mytitle">
>>>
>>> I poked around the types provided by Puppet and it looks like I should
>>> be able to do
>>>
>>> self[:servers]
>>>
>>> to access the property, but in practice that doesn't seem to work. It
>>> looks like the data I want is buried in the object, but I'm not sure of the
>>> correct means to get at it.
>>>
>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Puppet Users" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/puppet-users/5d8ea6d1-1afd-4983-a059-832d238eb6fa%40googlegroups.com
>>>
>>> <https://groups.google.com/d/msgid/puppet-users/5d8ea6d1-1afd-4983-a059-832d238eb6fa%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
--
You received this message because you are subscribed to the Google Groups
"Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/puppet-users/02a71e3b-e118-4d25-9535-411d9d610e55%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.