Reputation: 7441
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
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