[英]Puppet Facts - Searching Array of Objects
我在 Azure 台虛擬機上運行 Puppet 代理。
有一個名為“az_metadata”的自動生成的事實,其中包含有關機器的大量有用信息。
這是我正在嘗試搜索的 az_metadata 事實的片段:
"az_metadata":{
"compute":{
"tagsList":[
{
"name": "Comp"
"value": "Tech"
},
{
"name": "Dept"
"value": "R&D"
},
{
"name": "Env"
"value": "Dev"
},
{
"name": "Purp"
"value": "Port"
},
]
}
}
我從這個事實中需要的值是名稱為“Env”的 hash object 的值。 在上面的示例中,我要搜索的值是“Dev”。
獲得該價值的最佳方式是什么?
到目前為止我已經嘗試過:
我在 Puppet Agent 內部工作 Cmd 提示在客戶端進行調試。 我在代理機器上的 puppet.conf 中設置了 stringify_facts=false。
我可以通過運行來查看值:
$found = $facts[az_metadata][compute][tagsList][2]['value']
notify{"$found":}
退貨:
Notice: /Stage[main]/Main/Node[default]/Notify[Dev]/message: defined 'message' as 'Dev'
這看起來很有希望,但這在野外是行不通的,因為我不知道標簽的順序。所以,它可能在 object 2 或 1 或任何數量的元素中。 接下來,我想也許我可以迭代數組來找到我想要的值。
each($facts[az_metadata][compute][tagsList]) | $hash |{
if($hash['name'] == 'Environment'){
notify{ "$hash":
name => $hash[value]
}
$department = $hash[value]
}
}
notify { "Testing Fact Data":
name => $department,
}
這產生了既令人鼓舞又令人困惑的結果。 每個語句中的通知看起來是正確的,但是當我嘗試將該值保存到一個變量並稍后使用它時(在這種情況下,只是運行另一個通知),該值似乎是空白的。
Notice: Dev
Notice: /Stage[main]/Main/Node[default]/Notify[{name => Environment, value => Dev}]/message: defined 'message' as 'Dev'
Notice: Testing Fact Data
Notice: /Stage[main]/Main/Node[default]/Notify[Testing Fact Data]/message: defined 'message' as 'Testing Fact Data'
Notice: Applied catalog in 0.39 seconds
所以,它有點奏效。 但是我的變量沒有保存值? 我嘗試使用可變作用域,但沒有找到太多。 上面的代碼一點也不理想。 有沒有更好的辦法? 或者,有沒有辦法修復我不太好的遍歷數組的解決方案?
這產生了既令人鼓舞又令人困惑的結果。 每個語句中的通知看起來是正確的,但是當我嘗試將該值保存到一個變量並稍后使用它時(在這種情況下,只是運行另一個通知),該值似乎是空白的。
是的,我想這會讓很多人感到驚訝。
請始終記住,Puppet 變量只能設置一次。 但是,想要在您正在使用的代碼塊中使用變量是相對常見的,並且可能需要為代碼塊的不同執行將這些變量設置為不同的值。 出於這個原因,塊的每次執行都會為變量名稱建立一個本地 scope,其效果是塊內(通過賦值)創建的變量與塊外存在的任何同名變量分開且無關,並且來自在塊的不同執行期間創建的具有該名稱的任何變量。
另一方面,此類本地范圍是封閉 scope 的“子范圍”——例如由 class 或定義類型主體建立的范圍——這意味着在其父范圍中定義的名稱對它們是可見的,除非被本地定義。
請注意,大多數 Puppet 語句不會建立本地范圍。 代碼塊是您最有可能遇到的上下文。
出於您的目的,我將從使用 Puppet 的filter()
function 到 select 感興趣的哈希開始。 這可能看起來像這樣:
$envs = $facts['az_metadata']['compute']['tagsList'].filter() |$hash| {
$hash['name'] == 'Env'
}
結果將是那些名稱恰好為'Env'
的 tagsList 哈希值的數組。 如果您准備好假設總是只有一場比賽,那么您可以繼續
$department = $envs[0]['value']
對於有多個匹配但您不關心使用哪個的情況,這也可以。
另一方面,如果您想適應沒有匹配項的可能性,那么您可能需要使用dig()
function:
$department = $envs.dig(0, 'value')
如果沒有匹配項或第一個匹配項沒有'value'
鍵,這將為您提供undef
值而不是錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.