[chef] Re: Re: Re: detecting a node's role, acting on it, throws exception


Chronological Thread 
  • From: AJ Christensen < >
  • To:
  • Subject: [chef] Re: Re: Re: detecting a node's role, acting on it, throws exception
  • Date: Tue, 7 Feb 2012 21:43:36 +1300

I like to use:

if node.has_key? 'foo' and node['foo'].has_key? 'bar' and
  node['foo']['bar] =~ /bong/

It is the least gross when testing for the presence of like, three or
four nested keys. :)

Cheers,

AJ

On 7 February 2012 21:32,  
< >
 wrote:
> On Mon, 06 Feb 2012, Edward Sargisson wrote:
>
>> I'm catching up on email and seeing that nobody has replied.
>>
>> "i want to take certain actions on a host within a recipe depending on
>> what kind of role is defined for it. and by "role" i don't mean a chef
>> role .. necessarily. it's what role a node plays in the environment.
>> let's say i have hosts serving in various roles like: admin, app, proxy,
>> etc."
>> Er...<cough>... why not?
>> This would be exactly what a chef role is for - and by far the easiest way
>> to do it.
>
> yeah, you're probably right. i'm still getting a feel for how i want to
> describe my infrastructure in code using chef's tools. i'll try to
> revisit this. in the meantime, i chose to solve it like so:
>
>  x_privs = data_bag_item("hush", "x-perm-matrix")
>  if node[:wewt] && node[:wewt][:role]
>    if node[:wewt][:role].match /#{x_privs['roles_that_get_this']}/
>      grab_this = "X_SERVERCERT"
>      grab_that  = "X_PRIVATEKEY"
>    end
>  else
>    if node[:ec2][:userdata].match /#{x_privs['roles_that_get_this_legacy']}/
>      grab_this = "X_SERVERCERT"
>      grab_that  = "X_PRIVATEKEY"
>    end
>  end
>
>
>
> and i think i might get what's up with the error
>
>    NoMethodError - undefined method `[]' for nil:NilClass
>
> because i happened to read #chef log a few nites ago. if i may paraphrase
> erikh:
>
> when i try to reference node[:wewt][:role] on a node that doesn't have
> those attrs, it tries to apply the method #[] to nil, which isn't defined
> for NilClass (the class representation of the nil object).
>
> is that it?
>
> ::handwave:: i'm not a ruby coder .. yet
>
>
> kallen
>
>
>> On Wed, Feb 1, 2012 at 7:10 PM, 
>> < >
>>  wrote:
>>
>> >
>> > hello,
>> >
>> > hopefully not tl;dr :>  .. i'm approaching a task and i wonder if the
>> > style is appropriate. and if the style is appropriate, why is it
>> > throwing this exception?
>> >
>> > i want to take certain actions on a host within a recipe depending on
>> > what kind of role is defined for it. and by "role" i don't mean a chef
>> > role .. necessarily. it's what role a node plays in the environment.
>> > let's say i have hosts serving in various roles like: admin, app, proxy,
>> > etc.
>> >
>> > in particular, if a node is of role "admin", then i want to place on
>> > that node AWS credentials of a high privilege level. a node that is of
>> > role "app" i want to place low privileged AWS creds.
>> >
>> > in the recipe, i'm trying to create logic that detects the role from
>> > node attr data. maybe this is the wrong approach and i'd like feedback on
>> > that. but i also want to flesh out this approach to ask this question,
>> > which i guess comes down to a question on ruby syntax and the 
>> > non-presence
>> > of certain node attr data.
>> >
>> > (i will note that i just tried this by creating chef roles aws-role-admin
>> > and aws-role-generic, therein setting override attrs, and assigning
>> > those roles to my nodes. if the recipe calls upon attrs set by this
>> > chef role, it works. but is that the right way to solve this?)
>> >
>> > an additional data point is we have nodes that were launched with a
>> > legacy form of ec2 userdata, and i want to change the userdata to JSON
>> > going forward.
>> >
>> > legacy: "-r rolename -h hostname -e environment -v vol-xxxxxx"
>> >
>> > snippet from new JSON style:
>> >
>> >    "node_name": "test-kallen.dev.wewt.com",
>> >    "wewt": {
>> >      "role": "admin",
>> >      "environment": "dev",
>> >      "elip": "xx.xx.xx.xx",
>> >      "vol_list": [
>> >        "vol-xxxxx"
>> >      ]
>> >    },
>> >    "chef_server": "https://10.xx.xx.xx";,
>> >    "validation_client_name": "chef-validator",
>> >    "run_list": [
>> >      "role[base]",
>> >      "role[postfix-client]",
>> >      "recipe[and_so_on]"
>> >    ]
>> >
>> > my node launch process will take that userdata and populate it
>> > as chef node (normal) attributes.
>> >
>> > regardless of the style of userdata we pass in at launch time, that
>> > userdata is in the node attribute data in chef, be it at the top level
>> > under normal attr data or under [:ec2][:userdata]. so i figured i could
>> > test for the values in node attr data in my recipe. but the way i'm
>> > trying it is throwing an exception on legacy hosts for this line in
>> > the recipe:
>> >
>> >    if node[:ec2][:userdata] =~ /-r admin/ || node[:wewt][:role] == 
>> > "admin"
>> >
>> > here's a small test recipe that tries to detect the role as is present
>> > in node attr data. it tries to be backward compatible for the legacy
>> > userdata style.
>> >
>> > if node[:ec2]
>> >  if node[:ec2][:userdata] =~ /-r admin/ || node[:wewt][:role] == "admin"
>> >    Chef::Log.debug("HIGGS-BOSON: detected role admin")
>> >  elsif node[:ec2][:userdata] =~ /-r app/ || node[:wewt][:role] == "app"
>> >    Chef::Log.debug("HIGGS-BOSON: detected role app")
>> >  else
>> >    Chef::Log.debug("HIGGS-BOSON: no role detected!")
>> >  end
>> > end
>> >
>> >
>> > successful run on test-kallen.dev.wewt.com which contains the new node
>> > attributes via the new JSON userdata:
>> >
>> > [Thu, 02 Feb 2012 02:16:26 +0000] DEBUG: Loading Recipe test_recipe via
>> > include_recipe
>> > [Thu, 02 Feb 2012 02:16:26 +0000] DEBUG: Found recipe default in cookbook
>> > test_recipe
>> > [Thu, 02 Feb 2012 02:16:26 +0000] DEBUG: HIGGS-BOSON: detected role dev
>> > [Thu, 02 Feb 2012 02:16:26 +0000] DEBUG: Converging node
>> > test-kallen.dev.wewt.com
>> > [Thu, 02 Feb 2012 02:16:26 +0000] DEBUG: Saving the current state of node
>> > test-kallen.dev.wewt.com
>> >
>> >
>> >
>> >
>> > failed run on webapp01b.dev.wewt.com which does not contain the new
>> > node attributes:
>> >
>> > [Thu, 02 Feb 2012 02:16:28 +0000] DEBUG: Loading Recipe test_recipe via
>> > include_recipe
>> > [Thu, 02 Feb 2012 02:16:28 +0000] DEBUG: Found recipe default in cookbook
>> > test_recipe
>> > [Thu, 02 Feb 2012 02:16:28 +0000] ERROR: Running exception handlers
>> > [Thu, 02 Feb 2012 02:16:28 +0000] FATAL: Saving node information to
>> > /var/cache/chef/failed-run-data.json
>> > [Thu, 02 Feb 2012 02:16:28 +0000] ERROR: Exception handlers complete
>> > [Thu, 02 Feb 2012 02:16:28 +0000] DEBUG: Re-raising exception:
>> > NoMethodError - undefined method `[]' for nil:NilClass
>> > /var/cache/chef/cookbooks/test_recipe/recipes/default.rb:34:in 
>> > `from_file'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/cookbook_version.rb:578:in
>> > `load_recipe'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/mixin/language_include_recipe.rb:40:in
>> > `include_recipe'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/mixin/language_include_recipe.rb:27:in
>> > `each'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/mixin/language_include_recipe.rb:27:in
>> > `include_recipe'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/run_context.rb:72:in
>> > `load'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/run_context.rb:69:in
>> > `each'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/run_context.rb:69:in
>> > `load'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/client.rb:195:in
>> > `setup_run_context'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/client.rb:159:in
>> > `run'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/application/client.rb:239:in
>> > `run_application'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/application/client.rb:229:in
>> > `loop'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/application/client.rb:229:in
>> > `run_application'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/application.rb:67:in
>> > `run'
>> >  /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/chef-client:26
>> >  /usr/bin/chef-client:19:in `load'
>> >  /usr/bin/chef-client:19
>> > [Thu, 02 Feb 2012 02:16:28 +0000] FATAL: Stacktrace dumped to
>> > /var/cache/chef/chef-stacktrace.out
>> > [Thu, 02 Feb 2012 02:16:28 +0000] DEBUG: NoMethodError: undefined method
>> > `[]' for nil:NilClass
>> > /var/cache/chef/cookbooks/test_recipe/recipes/default.rb:34:in 
>> > `from_file'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/cookbook_version.rb:578:in
>> > `load_recipe'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/mixin/language_include_recipe.rb:40:in
>> > `include_recipe'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/mixin/language_include_recipe.rb:27:in
>> > `each'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/mixin/language_include_recipe.rb:27:in
>> > `include_recipe'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/run_context.rb:72:in
>> > `load'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/run_context.rb:69:in
>> > `each'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/run_context.rb:69:in
>> > `load'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/client.rb:195:in
>> > `setup_run_context'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/client.rb:159:in
>> > `run'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/application/client.rb:239:in
>> > `run_application'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/application/client.rb:229:in
>> > `loop'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/application/client.rb:229:in
>> > `run_application'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/application.rb:67:in
>> > `run'
>> > /usr/lib/ruby/gems/1.8/gems/chef-0.10.4/bin/chef-client:26
>> > /usr/bin/chef-client:19:in `load'
>> > /usr/bin/chef-client:19
>> > [Thu, 02 Feb 2012 02:16:28 +0000] FATAL: NoMethodError: undefined method
>> > `[]' for nil:NilClass
>> >
>> >
>> > so.. why does this throw the exception? i'm not a savvy ruby coder,
>> > but shouldn't the "or" in that line address the fact that
>> > node[:wewt][:role]
>> > doesn't exist for this node?
>> >
>> > if i edit this node's attr data and add in the new-style attributes, the
>> > run will succeed.
>> >
>> > i could go back and populate this node attr data for all legacy hosts,
>> > but i don't want to if i don't have to, if there's a better answer.
>> >
>> > thanks y'all,
>> > kallen
>> >
>> >



Archive powered by MHonArc 2.6.16.

§