使用哈希填充 ERB 模板失败,符号作为数组索引

Populating ERB template with hash fails with symbol as array index

我正在尝试使用内置于厨师食谱中的散列来填充 json 字符串,但一直出现错误 'Symbol as array index'。我在 Whosebug 和 google 上的搜索没有带我去任何地方,我只是好奇这里发生了什么。我对 Ruby 不是很好,所以如果代码有点偏差,请原谅我。

属性文件:

node.default[:server][:sumologic][:sources][:apache] = Hash.new
node.default[:server][:sumologic][:sources][:apache][:type] = "LocalFile"
node.default[:server][:sumologic][:sources][:apache][:name] = "Apache Logs"
node.default[:server][:sumologic][:sources][:apache][:path_expression] = "/var/log/httpd/*.log"
node.default[:server][:sumologic][:sources][:apache][:blacklist] = Array.new
node.default[:server][:sumologic][:sources][:apache][:blacklist] << "/var/log/httpd/access.log*"
node.default[:server][:sumologic][:sources][:apache][:blacklist] << "/var/log/httpd/error.log*"
node.default[:server][:sumologic][:sources][:apache][:blacklist] << "/var/log/httpd/ssl_request_log"
node.default[:server][:sumologic][:sources][:apache][:blacklist] << "/var/log/httpd/access_log"
node.default[:server][:sumologic][:sources][:apache][:blacklist] << "/var/log/httpd/error_log"
node.default[:server][:sumologic][:sources][:apache][:category] = "test-httpd"

模板 erb 文件:

{
  "api.version": "v1",
  "sources": [
    <% sources.each do |source| %>
    {
      "sourceType" : "<%= source[:type] %>",
      "name": "<%= source[:name] %>",
      "pathExpression": "<%= source[:path_expression] %>",
      <% if defined?(source[:blacklist]) %>
      "blacklist": [
        <% source[:blacklist].each do |listed, index| %>
        <%  if index < source[:blacklist].length - 1 %>
        "<%= listed %>",
        <%  else %>
        "<%= listed %>"
        <%  end %>
        <% end %>
      ],
      <% end %>
      "category": "<%= source[:category] %>"
    },
    <% end %>

...

食谱代码:

template '/opt/SumoCollector/sources.json' do
  source 'sources.json.erb'
  variables({
      :sources => node[:server][:sumologic][:sources]
  })
end

你对 chef 属性的用法有点不对。它们不是散列,而是更智能,因此您不必将它们初始化为散列。 删除行:

node.default[:server][:sumologic][:sources][:apache] = Hash.new

另外最好在 1 次操作中初始化数组属性:

node.default[:server][:sumologic][:sources][:apache][:blacklist] = [
  '/var/log/httpd/access.log*',
  '/var/log/httpd/error.log*',
  '/var/log/httpd/ssl_request_log',
  '/var/log/httpd/access_log',
  '/var/log/httpd/error_log'
]

你的错误"Symbol as array index"来自于你的情况

<% sources.each do |source| %>
  "sourceType" : "<%= source[:type] %>",
  [...]
<% end %>

source实际上是一个数组[:apache, <hash-like-object>],所以调用source[:type]失败。

sources 实际上是一个类似于散列的属性集合,您应该相应地处理它。如果您将行更改为那样

<% sources.each do |key, source| %>

一切都会好起来的。这里 key 将是 ":apache" 而 source 将等于 node[:server][:sumologic][:sources][:apache].