rubychef-infra

How to get the value in an array in default.rb in the recipe?


In attributes/default.rb, values are declared in below format.

default[:node][:action][:host_list] = [
  {
    :environment => 'dev',
    :application => 'appA',
    :server_name => 'serverA',
    :url => 'serverA.com'
  },
  {
    :environment => 'dev',
    :application => 'appB',
    :server_name => 'serverB',
    :url => 'serverB.com'
  },
  {
    :environment => 'test',
    :application => 'appA',
    :server_name => 'tserverA',
    :url => 'tserverA.com'
  },
  {
    :environment => 'test',
    :application => 'appB',
    :server_name => 'tserverB',
    :url => 'tserverB.com'
  }
]

From one of my recipes, how to retrieve the value of server_name and url (as reqd) from this default.rb?

I get env & app values from the data bag. I need the other values like server_name & url for using for eg. in a simple puts statement & a http invocation respectively.

Example:

:environment = dev & :application = appA (values read from databag)

I need the corresponding :server_name and :url from the host_list declaration in the default.rb so that the I get the values like below:

full_server_name = [:env]-[:app]-[:server_name] #=> dev-appA-serverA

puts :url #=> serverA.com

Solution

  • We can use the .select Ruby method to find the matching values from the (array of) Hashes and store it in variables. Then we can use these variables to form the expected output.

    As shown in your question for example, let's have :environment as dev, and :application as appA from databag.

    env = 'dev'
    app = 'appA'
    
    # first variable captures (two) hashes that have environment dev
    r1 = node[:node][:action][:host_list].select {|r| r[:environment] == env}
    
    # next variable collects the hash which contains appA
    r2 = r1.select {|r| r[:application] == app}
    
    # we can now use values from r2
    full_server_name = "#{r2[0][:environment]}-#{r2[0][:application]}-#{r2[0][:server_name]}"
    
    puts r2[0][:url]
    

    Note that we have to use the array index 0 since your original attribute is an array of Hashes.