Validation of attributes that can't have a sensible default

Hello everyone

For some cookbook attributes, you can not set a sensible default.

What i’m doing now is setting the attribute defaults to nil and creating a
_attribute_validation.rb recipe which is basically a sequence of:

unless foo[:attr]
Chef::Application.fatal! "foo[:attr] is unset. Override with sane values
of bar"
end

This is repetitive and boring. Is there a smarter way of going about this
which I’m missing?
Is there a way to do this directly from the attributes/*.rb ?

Thanks alot!

Sölvi Páll Á

Hi,

We actually have a bunch of approaches to address this problem.
However our favourite one is to use the "cutlery" helper cookbook [1]
and add snippets of code like

Check that the attribute node["foo"]["bar"]["baz"]["myattr"] exists

and is a string and return it
myattr = RealityForge::AttributeTools.ensure_attribute(node,
"foo.bar.baz.myattr", String)

Check that the attribute node["foo"]["mOtherAttr"] exists and return it

myOtherAttr = RealityForge::AttributeTools.ensure_attribute(node,
"foo.mOtherAttr")

We can also use the same approach to check contents of databags (pass
databag as first parameter). Of course
"RealityForge::AttributeTools.ensure_attribute" is really long so we
tend to shorten it to "ensure_attribute" via some ruby trickery.

HTH

[1] GitHub - realityforge/chef-cutlery: Cutlery is a Chef cookbook containing a collection useful library code.

On Thu, Oct 24, 2013 at 7:39 AM, Sölvi Páll Ásgeirsson solvip@gmail.com wrote:

Hello everyone

For some cookbook attributes, you can not set a sensible default.

What i'm doing now is setting the attribute defaults to nil and creating a
_attribute_validation.rb recipe which is basically a sequence of:

unless foo[:attr]
Chef::Application.fatal! "foo[:attr] is unset. Override with sane values
of bar"
end

This is repetitive and boring. Is there a smarter way of going about this
which I'm missing?
Is there a way to do this directly from the attributes/*.rb ?

Thanks alot!

Sölvi Páll Á

--
Cheers,

Peter Donald

Thanks Peter, this helps alot.

Cheers
Sölvi

On Thu, Oct 24, 2013 at 12:12 AM, Peter Donald peter@realityforge.orgwrote:

Hi,

We actually have a bunch of approaches to address this problem.
However our favourite one is to use the "cutlery" helper cookbook [1]
and add snippets of code like

Check that the attribute node["foo"]["bar"]["baz"]["myattr"] exists

and is a string and return it
myattr = RealityForge::AttributeTools.ensure_attribute(node,
"foo.bar.baz.myattr", String)

Check that the attribute node["foo"]["mOtherAttr"] exists and return it

myOtherAttr = RealityForge::AttributeTools.ensure_attribute(node,
"foo.mOtherAttr")

We can also use the same approach to check contents of databags (pass
databag as first parameter). Of course
"RealityForge::AttributeTools.ensure_attribute" is really long so we
tend to shorten it to "ensure_attribute" via some ruby trickery.

HTH

[1] GitHub - realityforge/chef-cutlery: Cutlery is a Chef cookbook containing a collection useful library code.

On Thu, Oct 24, 2013 at 7:39 AM, Sölvi Páll Ásgeirsson solvip@gmail.com
wrote:

Hello everyone

For some cookbook attributes, you can not set a sensible default.

What i'm doing now is setting the attribute defaults to nil and creating
a
_attribute_validation.rb recipe which is basically a sequence of:

unless foo[:attr]
Chef::Application.fatal! "foo[:attr] is unset. Override with sane
values
of bar"
end

This is repetitive and boring. Is there a smarter way of going about
this
which I'm missing?
Is there a way to do this directly from the attributes/*.rb ?

Thanks alot!

Sölvi Páll Á

--
Cheers,

Peter Donald

Out of curiosity, what is the ruby trickery you use to shorten the method
name?

Cheers,
Sölvi

On Thu, Oct 24, 2013 at 9:34 AM, Sölvi Páll Ásgeirsson solvip@gmail.comwrote:

Thanks Peter, this helps alot.

Cheers
Sölvi

On Thu, Oct 24, 2013 at 12:12 AM, Peter Donald peter@realityforge.orgwrote:

Hi,

We actually have a bunch of approaches to address this problem.
However our favourite one is to use the "cutlery" helper cookbook [1]
and add snippets of code like

Check that the attribute node["foo"]["bar"]["baz"]["myattr"] exists

and is a string and return it
myattr = RealityForge::AttributeTools.ensure_attribute(node,
"foo.bar.baz.myattr", String)

Check that the attribute node["foo"]["mOtherAttr"] exists and return it

myOtherAttr = RealityForge::AttributeTools.ensure_attribute(node,
"foo.mOtherAttr")

We can also use the same approach to check contents of databags (pass
databag as first parameter). Of course
"RealityForge::AttributeTools.ensure_attribute" is really long so we
tend to shorten it to "ensure_attribute" via some ruby trickery.

HTH

[1] GitHub - realityforge/chef-cutlery: Cutlery is a Chef cookbook containing a collection useful library code.

On Thu, Oct 24, 2013 at 7:39 AM, Sölvi Páll Ásgeirsson solvip@gmail.com
wrote:

Hello everyone

For some cookbook attributes, you can not set a sensible default.

What i'm doing now is setting the attribute defaults to nil and
creating a
_attribute_validation.rb recipe which is basically a sequence of:

unless foo[:attr]
Chef::Application.fatal! "foo[:attr] is unset. Override with sane
values
of bar"
end

This is repetitive and boring. Is there a smarter way of going about
this
which I'm missing?
Is there a way to do this directly from the attributes/*.rb ?

Thanks alot!

Sölvi Páll Á

--
Cheers,

Peter Donald

Hi,

I don't have the code in front of me but I think that in another
cookbook we add a snippet in a library file that looks something like

class Object
clazz = ::RealityForge::AttributeTools
clazz.public_methods.each do |m|
unless respond_to?(m)
define_method(m){p clazz.send(m)}
end
end
end

It is ugly and dangerous so don't do this at home :wink:

On Thu, Oct 24, 2013 at 9:20 PM, Sölvi Páll Ásgeirsson solvip@gmail.com wrote:

Out of curiosity, what is the ruby trickery you use to shorten the method
name?

Cheers,
Sölvi

On Thu, Oct 24, 2013 at 9:34 AM, Sölvi Páll Ásgeirsson solvip@gmail.com
wrote:

Thanks Peter, this helps alot.

Cheers
Sölvi

On Thu, Oct 24, 2013 at 12:12 AM, Peter Donald peter@realityforge.org
wrote:

Hi,

We actually have a bunch of approaches to address this problem.
However our favourite one is to use the "cutlery" helper cookbook [1]
and add snippets of code like

Check that the attribute node["foo"]["bar"]["baz"]["myattr"] exists

and is a string and return it
myattr = RealityForge::AttributeTools.ensure_attribute(node,
"foo.bar.baz.myattr", String)

Check that the attribute node["foo"]["mOtherAttr"] exists and return it

myOtherAttr = RealityForge::AttributeTools.ensure_attribute(node,
"foo.mOtherAttr")

We can also use the same approach to check contents of databags (pass
databag as first parameter). Of course
"RealityForge::AttributeTools.ensure_attribute" is really long so we
tend to shorten it to "ensure_attribute" via some ruby trickery.

HTH

[1] GitHub - realityforge/chef-cutlery: Cutlery is a Chef cookbook containing a collection useful library code.

On Thu, Oct 24, 2013 at 7:39 AM, Sölvi Páll Ásgeirsson solvip@gmail.com
wrote:

Hello everyone

For some cookbook attributes, you can not set a sensible default.

What i'm doing now is setting the attribute defaults to nil and
creating a
_attribute_validation.rb recipe which is basically a sequence of:

unless foo[:attr]
Chef::Application.fatal! "foo[:attr] is unset. Override with sane
values
of bar"
end

This is repetitive and boring. Is there a smarter way of going about
this
which I'm missing?
Is there a way to do this directly from the attributes/*.rb ?

Thanks alot!

Sölvi Páll Á

--
Cheers,

Peter Donald

--
Cheers,

Peter Donald