通过Ruby Recipe错误的厨师Data_bag用法?

时间:2014-10-23 16:32:36

标签: ruby chef databags

我有一个厨师DataBag,我正在尝试阅读和使用厨师食谱,并踢它我的屁股。请注意:我不是程序员,使用Chef是我第一次进入Ruby。

根据我在网上找到的示例,这里是我的Chef服务器上data_bags文件夹下的数据库“AWSProd”的内容,它位于一个名为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" : ""
      }
      ]
  }
}

在我的食谱中,我正在使用以下内容来获取Databag:

WEB = data_bag("WEB")
WEB_env_globals = data_bag_item("WEB", node.chef_environment)

然后我基本上想迭代每个站点(siteA,siteB等)并获取site_name,site_doc_root_folder等的各个值......

我试图回应价值观,所以我知道它们有效。我试过这个:

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

但是我收到了一个“无法将String转换为整数”的错误,在我有双##的行上。

然后我尝试用这样的东西替换那一行:

each_sitename = WEB_env_globals["hosted_sites"][site]["site_name"]

然后我得到一个“未定义的方法`[]'为nil:NilClass”在该行上的错误。

我知道我在这里遗漏了一些完全基本的东西,而且我一直在寻找一个小时的清晰解释而且找不到一个。帮帮我Ruby-Won-Kenobi ......

3 个答案:

答案 0 :(得分:1)

在您的数据包项目中,每个站点都是一个哈希数组。我不认为这是你的意图,因为你需要像以下一样访问它:

site[0]["site_name"]

你可能想要的是一个数据包项目,如:

{
  "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" : ""
      }
  }
}

答案 1 :(得分:0)

好的,所以我明白了!对Hash Vs Arrays进行了一些教育......

以下是正确的红宝石块:

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

答案 2 :(得分:0)

您在.each上使用Hash方法,但仅捕获密钥。 WEB_env_globals['hosted_sites'].each do |key, value| - 但您只为其指定了密钥的名称。

each_sitename = site[....] - 请记住该站点是键(String),因此您在[]上调用String方法,该方法需要一个Integer并返回该索引处的char。

* 您可以在任何ruby对象上调用.class以找出它是什么类型。这对于疑难解答非常有帮助

因此,您可以更改数据库以使用哈希数组:

更改您的资料库:

{
  "id" : "AWSProd",
  "hosted_sites" : [
    {
      "site_name" : "siteA",
      "site_doc_root_folder" : "siteA",
      "site_simlink" : ""
    },
    {
      "site_name" : "siteB",
      "site_doc_root_folder" : "siteB",
      "site_simlink" : ""
    }
  ]
}

或者不管它并为你的代码尝试这个:(注意我也没有使用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