在 ERB 中迭代一个灵活的范围

Iterating over a flexible range in ERB

我有一个 3.8.1 版的 Puppet ERB 模板,它抛出错误并拒绝工作。

这是我的原始代码:

<%= (1..5).select{ |i| "elastic%d" %[i] != @hostname }.map{|x, i| "elastic%d" %[x]} %>

这将创建一个主机名数组,不包括当前主机的主机名。

我正在尝试参数化我的模板,以便它可以根据集群中的服务器数量很好地扩展:

<%= (1..@(scope.lookupvar('mymodule::elastic_instances'))).select{ |i| "elastic%d" %[i] != @hostname }.map{|x, i| "elastic%d" %[x]} %>

这将引发以下异常:

Error: Could not run: /home/tk/puppet/modules/mymodule/templates/elasticsearch/elasticsearch-template.conf.erb:329: `@(' is not allowed as an instance variable name
/home/tk/puppet/modules/mymodule/templates/elasticsearch/elasticsearch-template.conf.erb:329: syntax error, unexpected end-of-input
; _erbout.concat(( (1..@(scope.lookupvar('mymodule...

我还尝试了以下替代方法:

<%= (1..@(scope.lookupvar('mymodule::elastic_instances'))).select{ |i| "elastic%d" %[i] != @hostname }.map{|x, i| "elastic%d" %[x]} %>
<%= (1..(scope.lookupvar('mymodule::elastic_instances'))).select{ |i| "elastic%d" %[i] != @hostname }.map{|x, i| "elastic%d" %[x]} %>
<%= (1..scope.lookupvar('mymodule::elastic_instances')).select{ |i| "elastic%d" %[i] != @hostname }.map{|x, i| "elastic%d" %[x]} %>

有没有我可以调用的手动方法来代替 Ruby 的语法糖?

事实证明,Puppet 返回的变量是字符串而不是 int,尽管我在 Puppet 中将其声明为 int。

通过转换和一些手动操作,我成功了:

<%= (Range.new(1, Integer(scope.lookupvar('mymodule::elastic_instances'))) ... %>

这让事情按预期工作。

如果您使用的是 PuppetDB,则可能需要查看 puppetdb-query module

使用它,您可以从数据库中检索主机名列表,这样模板就可以像

一样迭代它们
<% @elastic_search_hostnames.each do -%>
...
<% end -%>