我已根据这里非常简单的示例定义了一个自定义函数:https://docs.puppet.com/guides/custom_functions.html
var estadoSchema = Schema({
estado_nome: {
type :String,
unique : true
}
});
这种方式有效。我可以这样称呼它:
module Puppet::Parser::Functions
newfunction(:transform_service_hash) do |args|
filename = args[0]
hash_to_be_transformed = args[1]
File.open(filename, 'a') {|fd| fd.puts hash_to_be_transformed }
end
end
,文件显示:
$my_hash = { key => "value1" , key2 => "value2" }
notify{ "new hash!! $my_hash" :}
transform_service_hash('/var/tmp/blah',$my_hash)
但是,如果我尝试访问哈希的元素,则没有任何变化:
mgt21 ~ # cat /var/tmp/blah
keyvalue1key2value2
上述块将完全相同的数据输出到/ var / tmp / blah。
而且,有趣的是,如果我删除文件名pass并在模块中静态定义它:
module Puppet::Parser::Functions
newfunction(:transform_service_hash) do |args|
filename = args[0]
hash_to_be_transformed = args[1]
element1 = hash_to_be_transformed["key"]
File.open(filename, 'a') {|fd| fd.puts element1 }
end
end
和
$my_hash = { key => "value1" , key2 => "value2" }
notify{ "new hash!! $my_hash. element1 is: $my_hash.key" :}
transform_service_hash($my_hash)
我收到以下错误:" SERVER上的错误400:无法将哈希转换为字符串"使用指向" transform_service_hash($ my_hash)"
的行引用我是傀儡和红宝石的新手...所以我不确定我是不是正确地传递了元素,如果我没有正确地接收它,或者它是木偶无法处理的东西。请注意,我使用的是3.8版的木偶和1.8.7的红宝石。
感谢您的帮助。我一直在反对这一点,谷歌还没有到来。
---编辑以澄清我的目标(我还编辑了一些特殊的代码):我试图将一个哈希传递给puppet中的自定义ruby函数。 "测试" hash有两个元素:一个字符串和一个数组。它定义如下:
module Puppet::Parser::Functions
newfunction(:transform_service_hash) do |args|
hash_to_be_transformed = args[0]
element1 = hash_to_be_transformed["key"]
File.open('/var/tmp/blah2', 'a') {|fd| fd.puts element1 }
end
end
该功能如下所示:
$my_hash = { key => "value1" , key2 => ['array_value1', 'array_value2'] }
$my_display_element=$my_hash["key2"][0]
notify{ "new hash!! $my_hash. the first value of the array stored in element2 is: $my_display_element" :}
transform_service_hash('/var/tmp/blah',$my_hash)
现在,我只是希望能够看到我能够像哈希一样访问传递的哈希中的元素。所以我喜欢输出文件看起来像:
module Puppet::Parser::Functions
newfunction(:transform_service_hash) do |args|
filename = args[0]
hash_to_be_transformed = args[1]
element1 = args[1]["key"]
element2 = args[1]["key2"][0]
#element1 = hash_to_be_transformed["key"]
#element2 = hash_to_be_transformed["key2"][0]
File.open(filename, 'a') {|fd| fd.puts "hash_to_be_transformed: #{hash_to_be_transformed}\n" }
File.open(filename, 'a') {|fd| fd.puts "element1: #{element1}\n" }
File.open(filename, 'a') {|fd| fd.puts "element2: #{element2}\n" }
end
end
但是,在输出文件中,我看到:
hash_to_be_transformed: keyvalue1key2array_value1array_value2
element1: value1
element2: array_value1
显然,由于我的文本没有被添加,所以有些东西在这里,完整的哈希只打印出一次,看起来像字符串形式。
我认为这可能与我在传递文件名时所得到的错误有关(见上文)。我认为我的哈希被解释(或传递)为一个字符串,因此,我无法访问这些元素。不幸的是,我仍然无法验证这一点或弄清楚为什么会发生这种情况。
--- Edit2基于马特的答案。
我决定简化我的代码以隔离这个"无法将哈希转换为字符串错误"。我还提出了他的建议更改,以消除我的密钥声明中的含糊不清。
mgt21 ~ # cat /var/tmp/blah
keyvalue1key2array_value1array_value2
和
$my_hash = { 'key' => "value1" , 'key2' => ['array_value1', 'array_value2'] }
$my_display_element=$my_hash["key2"][0]
notify{ "new hash!! $my_hash. the first value of the array stored in element2 is: $my_display_element" :}
transform_service_hash($my_hash)
但是,我仍然会遇到相同的" Hash to String错误"。值得注意的是,我也尝试将哈希简化为:
module Puppet::Parser::Functions
newfunction(:transform_service_hash) do |args|
hash_to_be_transformed = args[0]
element1 = args[0]['key']
element2 = args[0]['key2'][0]
File.open('/var/tmp/blah', 'a') {|fd| fd.puts "hash_to_be_transformed: #{hash_to_be_transformed}\n" }
File.open('/var/tmp/blah', 'a') {|fd| fd.puts "element1: #{element1}\n" }
File.open('/var/tmp/blah', 'a') {|fd| fd.puts "element2: #{element2}\n" }
end
end
我仍然得到" Hash to String错误"。
答案 0 :(得分:1)
我快速获取了自定义解析器函数并将其转换为纯ruby,如下所示:
hash = { 'key' => 'value1', 'key2' => %w(array_value1 array_value2) }
def newfunction(filename, a_hash)
element1 = a_hash['key']
element2 = a_hash['key2'][0]
File.open(filename, 'a') do |fd|
fd.puts "hash_to_be_transformed: #{a_hash}"
fd.puts "element1: #{element1}"
fd.puts "element2: #{element2}"
end
end
newfunction('foo.txt', hash)
这会导致输出文本文件如下所示:
hash_to_be_transformed: {"key"=>"value1", "key2"=>["array_value1", "array_value2"]}
element1: value1
element2: array_value1
这似乎证实了我最初怀疑这里出了什么问题。你在Puppet中的哈希:
$my_hash = { key => "value1" , key2 => ['array_value1', 'array_value2'] }
具有隐式/模糊类型的键。在我用来测试的ruby代码中,我明确地将它们建立为字符串。这也与代码失败时的这些行强烈相关:
element1 = args[1]["key"]
element2 = args[1]["key2"][0]
和您的错误消息:
Error 400 on SERVER: can't convert Hash into String
因为您在ruby代码中指定了您希望键是字符串的。将Puppet中的哈希值更改为:
$my_hash = { 'key' => "value1" , 'key2' => "value2" }
应该解决这个问题。
在不相关的说明中,我建议使用短裤来帮助您学习这些语言。 Puppet-Lint,Rubocop和Reek都会帮助您指出代码的次优和杂乱部分,以帮助您学习新语言。
在相关的说明中,您可能希望在自定义解析器函数的顶部放置类似的内容:
raise(Puppet::ParseError, 'newfunction expects two arguments') if args.length != 2
答案 1 :(得分:0)
在咬牙切齿之后(以及来自@MattSchuchard的一些非常有用的指针),我意识到我的功能没有任何变化生效。每次更改自定义函数后,都需要重新启动puppetmaster服务:docs.puppet.com/guides/custom_functions.html(适当地在" Gotchas")。
一旦我在每次更改函数后开始重新启动此服务,我的哈希都能够正确解析:
来自.pp文件:
$filename = "/var/tmp/test"
$my_hash = { 'key' => "value1" , 'key2' => ["M\'lady\n*doffs cap*", 'array_value2'] }
transform_service_hash($filename, $my_hash)
来自ruby文件的:
module Puppet::Parser::Functions
newfunction(:transform_service_hash) do |args|
filename = args[0]
hash_to_be_transformed = args[1]
array_val = hash_to_be_transformed['key2'][0]
File.open(filename, 'a') {|fd| fd.puts "#{array_val}\n" }
end
end
并输出:
mgt21 tmp # cat test
M'lady
*doffs cap*