On Tue, Aug 11, 2015 at 12:57 PM <jwilki...@gmail.com> wrote:

> 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.
>
>
>
Ah yes, the old "no way to specify required attributes" thing. This should
work for required properties:

fail('... is required') if ! self[:servers] and ! self.provider.servers

And this should work for required parameters or properties:

fail('... is required') if ! self[:servers] and self[:ensure] != :absent


> On Tuesday, August 11, 2015 at 3:35:13 PM UTC-4, jwil...@gmail.com 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 memory serves me, in order of operation it gets called by the compiler
to validate resources being added to the catalog during compile (to catch
early validation failures), then it gets called during catalog application
to validate resources returned by self.prefetch (or self.instances if
running `puppet resource`) to make sure the system returned things that
make sense, and then finally called to validate each resource being
evaluated from the catalog during apply, because some things can only be
validated agent-side.


> 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 <jwil...@gmail.com> 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 puppet-users...@googlegroups.com.
>>>> 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 puppet-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/puppet-users/02a71e3b-e118-4d25-9535-411d9d610e55%40googlegroups.com
> <https://groups.google.com/d/msgid/puppet-users/02a71e3b-e118-4d25-9535-411d9d610e55%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 puppet-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-users/CAJaQvGDw1k7aJzt%2BYKU3h_0jDvwej6k24uA5MxNtZfKEvpdgHw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to