簡體   English   中英

Puppet Facts - 搜索對象數組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM