user1513388
user1513388

Reputation: 7441

Chef custom attributes

I'm working on a custom Chef Cookbook and have defined a custom attribute called default["server"]["apikey"] = nil thats been defined within the cookbook in a separate attributes file that looks like this:

#Default Attributes
default["webhooks"]["get_response"] = ""
default["webhooks"]["put_response"] = ""
default["webhooks"]["post_response"] = ""

default["server"]["username"] = "user"
default["server"]["password"] = "123"

default["server"]["apikey"] = nil 

Within my recipe I then do this:

webhooks_request "Request an API key from TPP " do
  uri "172.16.28.200/sdk/authorize/"
  post_data (
            { 'Username' => node["server"]["username"], 'Password' => node["server"]["password"]}
        )
  header_data (
              { 'content-type' => 'application/json'}
          )
  expected_response_codes [ 200, 201, 400 ]
  action :post
end

I then follow this with ruby_block that updates the value of the ``default["server"]["apikey"]` attribute with the API key like this:

ruby_block "Extract the API Key" do
  block do
    jsonData = JSON.parse(node["webhooks"]["post_response"])
    jsonData.each do | k, v |
      if k == 'APIKey'
        node.overide["server"]["apikey"] = v
      end
    end
  end
  action :run
end

I can then validate it using this:

ruby_block "Print API Key" do
  block do
    print "\nKey = : " + node["server"]["apikey"] + "\n"
  end
  action :run
end

However, if I then try to use the node["server"]["apikey"] attribute in a following block like this:

webhooks_request "Get data from TPP" do
  uri "127.0.0.1/vedsdk/certificates/retrieve?apikey=#{node["server"]["apikey"]}"
  post_data (
                { 'data' => "NsCVcQg4fd"}
        )
  header_data (
              { 'content-type' => 'application/json', 'auth' => node["server"] ["username"]}
              )
  expected_response_codes [ 200, 201, 400, 401 ]
  action :post
end

The value of node["server"]["apikey"]} is always empty. Interestingly though the value of the node["server"] ["username"] attribute is available and works as expected.

Obviously, I'm missing something here buy can't work out what :(

Upvotes: 1

Views: 1690

Answers (1)

Tensibai
Tensibai

Reputation: 15784

Writing it as a generic answer (it will avoid keeping it unanswered in list too ;))

When inside a resource you may evaluate an attribute value at converge time with lazy attribute evaluation.

The correct usage is

resource "name" do
  attribute lazy {"any value #{with interpolation} inside"}
end

The common error is to use lazy inside interpolation as we only want the variable to be lazy evaluated and there's only one.

By design lazy is meant to evaluate the attribute value, it can contain Ruby code to compute the value from something done by a previous resource too.

Upvotes: 2

Related Questions