Chef - 使用 ruby 脚本以编程方式编辑多个值

Chef - using a ruby script to edit multiple values programmatically

我正在尝试编写一个 ruby 脚本,以便我可以编辑由 knife search 命令生成的一堆节点的 run_lists。有人告诉我尝试使用 knife exec,但我得到的结果与我刚刚执行脚本的结果相同。

我正在使用由反引号指示的 OS 命令。第一个命令使用 knife search 工作,但是当我将这些结果输入到下面的 each_line 块时,它在脚本的注释中给出了错误。所以,显然第一部分是有效的,但第二部分不是,即使它的设置方式完全相同。

#!/usr/bin/env ruby
#
#
#

# %CORPCERT% = C:\Users\myuser\Documents\test\knife.rb
# This contains all the pointers to the client.pem, and other required files.

output = `knife search node "fqdn:node*test*.example.net" -i -c %CORPCERT%`

output.each_line do |result|
    #puts result
    puts "Adding run_list to #{result}"
    `knife node run_list add #{result} "role[role_zabbix_agent_corp_prod]" -c %CORPCERT%`
    #puts "#{exitcode}"
end

#C:\U\P028300\Desktop> knife exec apply_run_list.rb -c %CORPCERT%
# => Adding run_list to 8 items found
# => WARNING: No knife configuration file found
# => ERROR: Your private key could not be loaded from C:\chef\client.pem
# => Adding run_list to
# => WARNING: No knife configuration file found
# => ERROR: Your private key could not be loaded from C:\chef\client.pem
# => Adding run_list to nodeSTtestST0.example.net
# => WARNING: No knife configuration file found
# => ERROR: Your private key could not be loaded from C:\chef\client.pem
# => Adding run_list to nodeGWtestST0.example.net
# => WARNING: No knife configuration file found
# => ERROR: Your private key could not be loaded from C:\chef\client.pem
# => Adding run_list to nodeGWtestST1.example.net
# => WARNING: No knife configuration file found
# => ERROR: Your private key could not be loaded from C:\chef\client.pem
# => Adding run_list to nodeGWtestRT1.example.net
# => WARNING: No knife configuration file found
# => ERROR: Your private key could not be loaded from C:\chef\client.pem
# => Adding run_list to nodeGWtestRT2.example.net
# => WARNING: No knife configuration file found
# => ERROR: Your private key could not be loaded from C:\chef\client.pem
# => Adding run_list to nodeSTtestRT0.example.net
# => WARNING: No knife configuration file found
# => ERROR: Your private key could not be loaded from C:\chef\client.pem
# => Adding run_list to nodeGWtestRT3.example.net
# => WARNING: No knife configuration file found
# => ERROR: Your private key could not be loaded from C:\chef\client.pem
# => Adding run_list to nodeGWtestRT0.example.net
# => WARNING: No knife configuration file found
# => ERROR: Your private key could not be loaded from C:\chef\client.pem

我知道我没有正确执行 knife exec 命令,文档让我感到困惑。我还没有找到任何与我正在尝试做的事情相近或相关的例子。我应该如何尝试以编程方式搜索节点,然后更新或将项目添加到它们的 run_list?

一个更简单的解决方案是使用 ridley,Chef 服务器的 ruby API 库:

require 'ridley'

Ridley::Logging.logger.level = Logger.const_get 'ERROR'

ridley = Ridley.from_chef_config("C:\Users\myuser\Documents\test\knife.rb", {:ssl => {:verify => false}})

ridley.search(:node, "fqdn:node*test*.example.net").each { |n|
  n.merge_data(:run_list => ["role[role_zabbix_agent_corp_prod]"])
  n.save
}

这就是我在与一些朋友和 IRC 聊天室交谈后为了完成我想做的事情所做的。

# similar to knife search node "fqdn:WSO2*"
search("node", "fqdn:WSO2*").each do |search_node|
    # This looks at the array of the node information, and if the 
    # run_list already exists, do nothing and move on. 
    unless search_node.run_list.include?("role[role_zabbix_agent_corp_prod]")
        # This adds the listed role, or recipe to the end of the run_list
        search_node.run_list.push "role[role_zabbix_agent_corp_prod]"
        # Save the modifications.
        search_node.save
    end #=> End Unless
end #=> End Search
# Make sure to add this to the end, or it will continue to keep running. 
exit 0

将上述脚本放入名为 script.rb 和 运行 的文件中:

knife exec script.rb

通读后 knife exec and also, chef-shell, I had to play around with the data structures and figure out how they were presented by Chef. The site here: http://www.bonusbits.com/main/Reference:Chef_Node_Data_Structure and http://www.bonusbits.com/main/Reference:Chef_Shell 也帮了大忙。我希望这可以帮助那些想要更多地了解 Chef 的人。

一个简单的方法:

knife exec -E 'nodes.transform("fqdn:WSO2*") { |n| n.run_list << "role[role_zabbix_agent_corp_prod]" }'

nodes.transform 处理搜索循环和保存(只要块不 return nil/false)并且 RunList#<< 已经检查它是否已经在运行列表。