微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 Chef.event_handler 时是否可以访问 run_status 对象?

如何解决使用 Chef.event_handler 时是否可以访问 run_status 对象?

我有一个似乎无法找到解决方案的 catch-22。我可以成功地做到这一点:

#
# Cookbook:: core_unix_base_cmcb
# Recipe:: email_on_fail

email_hash = node.default['core_unix_base_cmcb']['email_hash']
email_hash['mailserver'] = node['postfix']['main']['relayhost']
email_hash['subject'] = "Subject: Chef-client run Failed on #{email_hash['hostname']}"
email_hash['message'] = "A Chef-client run Failed on #{email_hash['hostname']}."
email_hash['recipient'] = [ 'someone@somewhere.com' ]

Chef.event_handler do
  on :run_Failed do
    SendEmail::Helper.new.send_email(email_hash)
  end
end
require 'net/smtp'

module SendEmail
  class Helper
    def send_email(email_hash)
      msg = "From: #{email_hash[:sender]} < #{email_hash[:sender]}@#{email_hash[:hostname]}\n"
      msg << "To: #{email_hash[:recipient].join('; ')}\n"
      msg << "#{email_hash[:subject]}\n"
      msg << "Date: #{Time.Now.rfc2822}\n\n"
      msg << "#{email_hash[:message]}\n"
      sender = 'chef-client-noreply@somewhere.com'
      Net::SMTP.start(email_hash[:mailserver],25) do |smtp|
        smtp.send_message msg,sender,email_hash[:recipient]
      end
    end
  end
end

但是 - 我需要消息包含厨师客户端 run_status。 如果添加

msg << "#{run_status.formatted_exception}\n"
msg << Array(backtrace).join('\n')

对于上面的例子,run_status 没有定义。

我能找到的唯一示例是使用报告界面的自定义处理程序和chef_handler 资源声明。所以我尝试了这个(从我发现的一个例子中):

chef_handler 'SendEmailOnFail::SendEmail' do # Full class name
  # relative path to your handler
  source ::File.expand_path('../../files/default/handlers/email_on_fail_helper.rb',__FILE__)
  # source 'email_on_fail_helper.rb'
  arguments email_hash  # Hash or Array to pass to handler constructor
end
require 'net/smtp'

module SendEmailOnFail
  class SendEmail < Chef::Handler
    def report(email_hash)
      if run_status.Failed?
        msg = "From: #{email_hash[:sender]} < #{email_hash[:sender]}@#{email_hash[:hostname]}\n"
        msg << "To: #{email_hash[:recipient].join('; ')}\n"
        msg << "#{email_hash[:subject]}\n"
        msg << "Date: #{Time.Now.rfc2822}\n\n"
        msg << "#{email_hash[:message]}\n"
        msg << "#{run_status.formatted_exception}\n"
        msg << Array(backtrace).join('\n')
        sender = 'chef-client-noreply@somewhere.com'
        Net::SMTP.start(email_hash[:mailserver],25) do |smtp|
          smtp.send_message msg,email_hash[:recipient]
        end
      end
    end
  end
end

当您使用该代码执行厨师客户端运行时,它会在参数上出错(收到 1,预期为 0)。 我在网上绝对没有发现 def report 有任何参数的例子,所以我认为这就是问题所在。我们的组织需要这些参数,因为邮件服务器并不总是相同的,收件人也不总是相同的。

那么我怎样才能在电子邮件正文中获取厨师客户端运行失败的信息,并将参数传递给库(或自定义处理程序)? 提前致谢。

解决方法

run_status 仅适用于 documentation 中所述的 report 接口。

run_status 对象在为任何处理程序运行 report 接口之前由 Chef Infra Client 初始化。

不过……

那么我如何才能在电子邮件正文中获取厨师客户端运行失败的信息,并将参数传递给库(或自定义处理程序)?

可以run_failedevent_handler 块中获取异常详细信息。其中一些方法是:messagebacktracefull_message 等。

有一个关于为 :run_failedhere 设置变量的参考。

例如,在我的食谱中,我将 message 添加到我的 email_hash。然后将其传递给用于发送电子邮件的辅助方法。

# Adding this for completeness,the required change is in "Chef.event_handler" block
email_hash = Hash.new
email_hash['node_name'] = Chef.run_context.node.name
email_hash['subject'] = "Chef run failed on #{email_hash['node_name']}"
email_hash['sender'] = 'admin@example.io'
email_hash['recipient'] = 'user@example.io'

# This is where we can access details of "exception"
Chef.event_handler do
  on :run_failed do |exception|
    email_hash['error_msg'] = exception.message
    SendEmail::Helper.new.send_email(email_hash)
  end
end

再次添加我的 SendEmail helper library 以确保完整性:

require 'net/smtp'

module SendEmail
  class Helper

    def send_email(email_hash)
      message = "From: #{email_hash['sender']}\n"
      message << "To: #{email_hash['recipient']}\n"
      message << "Subject: #{email_hash['subject']}\n"
      message << "Date: #{Time.now.rfc2822}\n\n"
      message << "Chef run failed on #{email_hash['node_name']}\n"
      message << "#{email_hash['error_msg']}\n"
      Net::SMTP.start('localhost',25) do |smtp|
        smtp.send_message message,email_hash['sender'],email_hash['recipient']
      end
    end

  end
end
,

一种解决方法是将 email_hash 设置为一个属性,报告处理程序可以使用节点方法访问节点对象 o 您可以执行 run_status.node['email_hash'][xxx] 而不是 email_hash[xxx]

处理程序中 run_status 对象周围的文档是 here

要进行更详细的交流,请随时加入 Chef 的 slack 以获得社区帮助(那里也有 Chef 的开发人员,这对内部位提供了很多帮助):https://community-slack.chef.io/

,

谢谢两位的回复。在发布我的问题后继续在互联网上搜索之后,我终于遇到了一个我可以使用的金块。 https://github.com/chef/chef/issues/7101

我很幸运有这个例子:

on :run_failed do |exception,run_status|

我真的不明白它是如何工作的,或者它在哪里记录,但它与你正在做的事情本质上是一样的,seshadri_c,并且运行良好。我可以访问撰写消息所需的内容,例如

run_status.run_context.cookbook_collection

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?