2016-08-19 97 views
1

我已經定義了目前基於這裏很簡單的例子一個自定義函數:https://docs.puppet.com/guides/custom_functions.html如何將散列傳遞給puppet中的自定義函數?

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 

但是,如果我嘗試訪問哈希的元素,沒有什麼變化:

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 

以上塊將完全相同的數據輸出到/ var/tmp/blah。

而且,有趣的是,如果我刪除的文件名通和模塊中靜態地定義它:

$my_hash = { key => "value1" , key2 => "value2" } 
    notify{ "new hash!! $my_hash. element1 is: $my_hash.key" :} 
    transform_service_hash($my_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 

我得到以下錯誤:「錯誤400服務器: ($ my_hash)「

我是新來的木偶和紅寶石......所以我不確定我不是正確傳遞元素,如果我沒有正確接收它,或者它是木偶無法處理的東西。請注意,我使用的是木偶版本3.8和紅寶石版本1.8.7。

感謝您的任何幫助。我一直在抨擊我的頭,谷歌還沒有到來。

---編輯,以澄清我的目標(我也編輯了我的代碼一點特異性):我試圖傳遞一個散列到木偶內的自定義ruby函數。 「測試」散列有兩個元素:一個字符串和一個數組。它被定義爲這樣的:

$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 

然而,在輸出文件中,我看到:

mgt21 ~ # cat /var/tmp/blah 
keyvalue1key2array_value1array_value2 

顯然,事情是在這裏過的沒有被加了我的文字完整的散列只是打印出來一次,看起來像字符串形式。

我相信這可能與我沒有傳入文件名時得到的錯誤有關(見上文)。我認爲我的散列正在被解釋(或傳遞)爲一個字符串,因此,我無法訪問這些元素。不幸的是,我仍然無法驗證這一點或找出它可能發生的原因。

--- Edit2基於Matt的回答如下。

我決定簡化我的代碼以隔離這個「無法將哈希轉換爲字符串錯誤」。我還提出了他的建議更改,以消除我的關鍵聲明中的含糊之處。

$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) 

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 

但是,我還是結了相同的 「散列到字符串錯誤」。值得注意的是,我也嘗試簡化我的散列:

$my_hash = { 'key' => "value1" , 'key2' => "value2" } 

我仍然得到「哈希到字符串錯誤」。

+0

你能做出更正你的代碼,以準確反映你做了什麼?當你的開始的例子有一個方法需要兩個參數,你只提供一個參數,然後你在執行過程中顯示的代碼沒有致命錯誤時,它不可能是準確的。 –

+0

對不起,我必須粘貼第二個例子的調用(在函數本身中定義filepath之後)。我修復了它。 – brbcoffee

+0

你能告訴我們你想要什麼格式的「/ var/tmp/blah」嗎?你似乎正在傳遞一個哈希,但我不知道你想如何在文件中查找。 – kcdragon

回答

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* 
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 

這似乎證實我最初懷疑這裏出了什麼問題。您在木偶中的散列:

$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代碼指定。改變你的木偶散列爲:

$my_hash = { 'key' => "value1" , 'key2' => "value2" } 

應該解決這個問題。

在一個不相關的說明中,我建議使用棉絨幫助您學習這些語言。 Puppet-Lint,Rubocop和Reek都會幫助您指出代碼中不理想和凌亂的部分,以幫助您學習新的語言。

在一個相關的說明,您可能希望把這樣的事情在你自定義的解析器函數的頂部:

raise(Puppet::ParseError, 'newfunction expects two arguments') if args.length != 2 
+0

非常感謝您的繼續幫助。我嘗試了同樣的純紅寶石功能,並且按預期工作(當然)。 我絕對同意你的看法,當傳遞這個散列值時它似乎是不正確的語法。我決定簡化我的代碼,專注於「無法將哈希轉換爲字符串錯誤。」 我將在上面的編輯部分中添加最新的代碼塊。 – brbcoffee

+1

爲了上天,我需要每次重新啓動puppetmaster服務第二個要點在這裏:https://docs.puppet.com/guides/custom_functions.html /facepalm – brbcoffee

+0

@EricYoung是的重新啓動Puppetmaster是自定義分析器函數中的主要煩惱之一在Puppet 4.3中此外,您還可以執行Puppet DSL函數和Puppet非分析器自定義函數(後者的設置非常奇怪),不需要重新啓動。 –

相關問題