Chef 自定义资源:可变 属性 或替代方案
Chef Custom Resources : mutable property or an alternative
我读到 2016
OpsCode 反对 LWRP
和替代 HWRP
。他们更推荐使用 custom resources
.
虽然这是有道理的,但在利用 ruby 方面还有很多不足之处(除非我误解了?)
我希望能够根据一些布尔属性修改数组。然后我可以使用该数组传递给模板,如:
property :get_iptables_info, [TrueClass, FalseClass], default: false
property :get_pkglist, [TrueClass, FalseClass], default: false
property :cw_logs, Array, default: [], required: false
action :create do
ruby_block 'cw_iptables' do
block do
new_resource.cw_logs.push({ "#{new_resource.custom_dir}/iptables/iptables.txt" => { "log_group_name" => new_resource.log_group_name+"/iptables"}})
end
action :run
only_if {new_resource.get_iptables_info}
end
template "my_template" do
variables ({:logstreams => cw_logs})
end
end
然后在我的模板中:
<% @logstreams.each_pair do |path, _object| %>
["#{path}"]
log_group_name = _object["log_group_name"]
<% end %>
问题是属性 immutable
。所以我得到错误:
RuntimeError
------------
ruby_block[cw_iptables] (/tmp/kitchen/cache/cookbooks/custom_cw/resources/logs.rb line 43) had an error: RuntimeError: can't modify frozen Array
正确的做法是什么?在资源中编写 ruby 代码以使其更加模块化并使用 methods/functions
的正确方法是什么?
改变自定义资源内的属性通常不是一个好主意(也有例外,但这不是其中之一)。更好的方法是使用局部变量。相关的,当您已经在自定义资源的操作中时,您不需要像那样使用 ruby_block:
action :create do
cw_logs = new_resource.cw_logs
if new_resource.get_iptables_info
cw_logs += [whatever extra stuff you want]
end
template "my_template" do
variables logstreams: cw_logs
end
end
值得注意的是,它使用的是 +=
而不是推送,它不会改变原始内容。如果你使用 push
你会想要 cw_logs = new_resource.cw_logs.dup
或类似的。
我读到 2016
OpsCode 反对 LWRP
和替代 HWRP
。他们更推荐使用 custom resources
.
虽然这是有道理的,但在利用 ruby 方面还有很多不足之处(除非我误解了?)
我希望能够根据一些布尔属性修改数组。然后我可以使用该数组传递给模板,如:
property :get_iptables_info, [TrueClass, FalseClass], default: false
property :get_pkglist, [TrueClass, FalseClass], default: false
property :cw_logs, Array, default: [], required: false
action :create do
ruby_block 'cw_iptables' do
block do
new_resource.cw_logs.push({ "#{new_resource.custom_dir}/iptables/iptables.txt" => { "log_group_name" => new_resource.log_group_name+"/iptables"}})
end
action :run
only_if {new_resource.get_iptables_info}
end
template "my_template" do
variables ({:logstreams => cw_logs})
end
end
然后在我的模板中:
<% @logstreams.each_pair do |path, _object| %>
["#{path}"]
log_group_name = _object["log_group_name"]
<% end %>
问题是属性 immutable
。所以我得到错误:
RuntimeError
------------
ruby_block[cw_iptables] (/tmp/kitchen/cache/cookbooks/custom_cw/resources/logs.rb line 43) had an error: RuntimeError: can't modify frozen Array
正确的做法是什么?在资源中编写 ruby 代码以使其更加模块化并使用 methods/functions
的正确方法是什么?
改变自定义资源内的属性通常不是一个好主意(也有例外,但这不是其中之一)。更好的方法是使用局部变量。相关的,当您已经在自定义资源的操作中时,您不需要像那样使用 ruby_block:
action :create do
cw_logs = new_resource.cw_logs
if new_resource.get_iptables_info
cw_logs += [whatever extra stuff you want]
end
template "my_template" do
variables logstreams: cw_logs
end
end
值得注意的是,它使用的是 +=
而不是推送,它不会改变原始内容。如果你使用 push
你会想要 cw_logs = new_resource.cw_logs.dup
或类似的。