[英]Chef Data_bag usage via Ruby Recipe error?
I have a Chef DataBag that I'm trying to read and use inside of a chef recipe, and its kicking my ass. 我有一个Chef DataBag,我正在尝试在厨师食谱中阅读和使用它,这让我大吃一惊。 Please note: I'm not a programmer, and the use of Chef is my first entry into Ruby. 请注意:我不是程序员,而使用Chef是我第一次进入Ruby。
Based off of the examples I've found online, here is the contents of the databag "AWSProd" that lives in a folder called WEB under the data_bags folder on my Chef server: 根据我在网上找到的示例,这是数据包“ AWSProd”的内容,该数据包位于Chef服务器上data_bags文件夹下的WEB文件夹中:
{
"id" : "AWSProd",
"hosted_sites" : {
"siteA" : [
{
"site_name" : "siteA",
"site_doc_root_folder" : "siteA",
"site_simlink" : ""
}
],
"siteB" : [
{
"site_name" : "siteB",
"site_doc_root_folder" : "siteB",
"site_simlink" : ""
}
]
}
}
In my recipe, I'm using the following to grab the Databag for use: 在我的食谱中,我使用以下方法来获取Databag以便使用:
WEB = data_bag("WEB")
WEB_env_globals = data_bag_item("WEB", node.chef_environment)
Then I basically want to iterate each site (siteA, siteB, etc) and grab those individual values for site_name, site_doc_root_folder, etc... 然后我基本上想遍历每个站点(siteA,siteB等),并获取site_name,site_doc_root_folder等的各个值。
I'm trying to just echo the values so I know they work. 我正在尝试仅回显值,以便我知道它们起作用。 I tried this: 我尝试了这个:
WEB_env_globals["hosted_sites"].each do |site|
each_sitename = site["site_name"] ## can't convert String into Integer
each_site_doc_root_folder = site["site_doc_root_folder"]
each_site_simlink = site["site_simlink"]
execute "echo each site" do
command "echo #{each_sitename} #{each_site_doc_root_folder} #{each_site_simlink}"
action :run
end
end
But I received a "can't convert String into Integer" error on the line where I have the double ##. 但是我在双倍##的行上收到“无法将String转换为Integer”错误。
Then I tried replacing that line with something like this: 然后我尝试用以下内容替换该行:
each_sitename = WEB_env_globals["hosted_sites"][site]["site_name"]
But then I get an "undefined method `[]' for nil:NilClass" error on that line. 但是然后我在那一行上得到了“ nil:NilClass的未定义方法'[]'”错误。
I know I'm missing something completely basic with Ruby here, and I've been looking for about an hour for a clear explanation and cant find one. 我知道我在这里缺少Ruby的一些基本知识,并且我一直在寻找一个清晰的解释一个小时,却找不到一个。 Help me Ruby-Won-Kenobi... 帮我Ruby-Won-Kenobi ...
In your data bag item, each site is an array of hashes. 在您的数据袋项目中,每个站点都是一个哈希数组。 I don't think this is what you intended, since you would need to access it like: 我认为这不是您想要的,因为您需要像这样访问它:
site[0]["site_name"]
What you probably wanted was a data bag item like: 您可能想要的是一个数据袋物品,例如:
{
"id" : "AWSProd",
"hosted_sites" : {
"siteA" : {
"site_name" : "siteA",
"site_doc_root_folder" : "siteA",
"site_simlink" : ""
},
"siteB" : {
"site_name" : "siteB",
"site_doc_root_folder" : "siteB",
"site_simlink" : ""
}
}
}
Ok, so I got it! 好的,我明白了! Took a little education on Hash Vs Arrays... 对Hash Vs Arrays进行了一些教育...
Below is the correct ruby block: 以下是正确的红宝石块:
WEB_env_globals["hosted_sites"].each do |site,data|
data.each do |hash|
each_sitename = hash["site_name"]
each_site_doc_root_folder = hash["site_doc_root_folder"]
each_site_simlink = hash["site_simlink"]
execute "echo each site #{site}" do
command "echo #{each_sitename} #{each_site_doc_root_folder} #{each_site_simlink}"
action :run
end
end
end
You are using the .each
method on a Hash
, but only capturing the key. 您在Hash
上使用.each
方法,但仅捕获密钥。 WEB_env_globals['hosted_sites'].each do |key, value|
- but you only gave it a name for the key. -但您只给它起了钥匙的名字。
each_sitename = site[....]
- remember that site is the key (a String), so you're calling the []
method on String
which expects an Integer and returns the char at that index. each_sitename = site[....]
-请记住,站点是键(一个String),因此您要在String
上调用[]
方法,该方法需要一个Integer并在该索引处返回char。
* You can call .class
on any ruby object to find out what type it is. * 您可以在任何ruby对象上调用.class
来找出它是什么类型。 This is very helpful for troublshooting 这对于故障排除非常有帮助
So you can change your databag to use an array of hashes: 因此,您可以更改数据包以使用哈希数组:
change your databag: 更改您的数据包:
{
"id" : "AWSProd",
"hosted_sites" : [
{
"site_name" : "siteA",
"site_doc_root_folder" : "siteA",
"site_simlink" : ""
},
{
"site_name" : "siteB",
"site_doc_root_folder" : "siteB",
"site_simlink" : ""
}
]
}
Or leave it alone and try this for your code: (note I also don't use an execute
block for my debugging) 或不理会它,并为您的代码尝试一下:(请注意,我也没有使用execute
块进行调试)
WEB_env_globals["hosted_sites"].each do |sitename, site_array|
site_array.each do |site|
each_sitename = site["site_name"]
each_site_doc_root_folder = site["site_doc_root_folder"]
each_site_simlink = site["site_simlink"]
Chef::Log.debug "#{each_sitename} #{each_site_doc_root_folder} #{each_site_simlink}"
# you could use puts or a higher level log message to make this easier to see in your output.
end
end 结束
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.