4

Please see the following code, using the log resource in chef.

log 'Hello there' do
  level :info
  notifies :run, "log_to_chat('Hello there')"
end

Is there a way to refer to the resource name (in this case: 'Hello there') when I pass it to the function log_to_chat.

I imagine something like:

log 'Hello there' do
  level :info
  notifies :run, "log_to_chat(#{name})"
end

Adding my attempts for log_to_chat.

Attempt 1:

resource_name :log_to_chat

property :message, kind_of: String, name_property: true

chat_url = 'https://chat.server/abcdef'

action :run do
  execute do
    command "curl -m 5 -i -X POST -d \"payload={...}\" #{chat_url}"
    ignore_failure true
  end
end

Question: how to pass the :message parameter as a one liner from the notifies line?

notifies :run, "log_to_chat[message]", --pass :message how??--

Attempt 2:

module Chat
  def log_to_chat(message)
    chat_url = 'https://chat.server/abcdef'
    action :run do
      execute "curl" do
        command "curl -m 5 -i -X POST -d \"payload={...}\" #{chat_url}"
        ignore_failure true
      end
    end
  end
end

edit: attempt 2 didn't work since you can't use resources in a definition

vikingsteve
  • 38,481
  • 23
  • 112
  • 156

2 Answers2

3

You can refer to the name variable. From documentation you can read that "name is the name of the resource block". Keep in mind that you want to use the name of block (which is Hello there in your case) instead of resource name (which is log in the snippet from question)

StephenKing
  • 36,187
  • 11
  • 83
  • 112
Maciej Małecki
  • 2,725
  • 19
  • 29
  • Ok, thanks, is it then: `notifies :run, "log_to_chat(#{name})"` ? – vikingsteve Aug 19 '16 at 12:16
  • well it depends on your code base, but `log_to_chat[#{name}]` is more likely . https://docs.chef.io/resource_common.html#notifies – Maciej Małecki Aug 19 '16 at 12:18
  • Any chance to guide me on how to write the `log_to_chat` part, would that be a method in a module, or a custom resource, or how? It's basically a single `curl` command. – vikingsteve Aug 19 '16 at 12:53
  • You can have for example a ruby block for that: https://docs.chef.io/resource_ruby_block.html. – Maciej Małecki Aug 19 '16 at 12:55
  • You can use `declared_key` for a cleaner alternative: `notifies :run, declared_key` https://github.com/chef/chef/blob/e6167aa5fe2decfe2395012c302360fc50054b9c/lib/chef/resource.rb#L1368 – tterrace Mar 11 '20 at 18:09
1

If you want to notify resource log_to_chat[some message] (Attempt 1) you will have to explicitly declare it with action :nothing before log 'Hello there'. So it should look like this:

log_to_chat 'some message' do
  action :nothing
end

log 'Hello there' do
  level :info
  notifies :run, "log_to_chat[some message]"
end

Where it's valid code, it isn't best solution. To have 100% chef way solution, you should implement new log resource provider, by default it's Chef::Provider::ChefLog. You should implement 'Old School LWRP' provider mentioned here. In your new provider you can replace standard chef log resource functionality or just extend it by your curl calls or native net/http (or any other network gem) ruby calls (preferred).

Szymon
  • 1,525
  • 1
  • 11
  • 12
  • Ok, thanks. How would I pass the `#{name}` to `log_to_chat[some message]` as a parameter or property from the `notifies...` line? (in this case, 'Hello there') – vikingsteve Aug 22 '16 at 08:20
  • I'm not sure if it's possible, I would extract it to variable before both resources. – Szymon Aug 22 '16 at 09:40