使用.map(或其他stdlib功能)创建哈希而不是数组

时间:2019-07-19 14:32:53

标签: arrays hash puppet hiera

我正在尝试针对云中的JMS服务器,人偶模块init.pp需要向哈希添加密钥。

我正在读取一个层的希拉,必须提取其中的一部分以形成新的哈希。 .each不返回任何值,因此我正在使用.map。 我得到的值完全符合我的要求,但是当我尝试deep_merge时,我发现.map输出为数组。

service.yaml

jms_subdeployment_instances:
   'BPMJMSModuleUDDs:BPMJMSSubDM':
      ensure:     'present'
      target:
       - 'BPMJMSServer_auto_1'
       - "BPMJMSServer_auto_%{::ec2_tag_name}"
      targettype:
        - 'JMSServer'
        - 'JMSServer'      

init.pp

  $jms_subdeployments = lookup('jms_subdeployment_instances', $default_params)
  $jms_target_args = $jms_subdeployments.map |$subdep, $value| {
    $jms_short_name = $subdep[0, 3]
    $jms_subdeployment_inst = $array_domain_jmsserver_addresses.map |$index, $server| {
      "${jms_short_name}JMSServer_auto_${server}"

      if defined('$jms_subdeployment_inst') {
        $jmsTargetArg = {
          "${subdep}" => {
            'target' => $jms_subdeployment_inst
          }
        }
      }
    }

  $merge_subdeployment_targets = merge($jms_subdeployments, $jms_target_args)



```Output
New JMS targets are : [{BPMJMSModuleUDDs:BPMJMSSubDM => {target => [BPMJMSServer_auto_server101, BPMJMSServer_auto_server102]}}]

括起来的[]给我带来麻烦。据我所知,在puppet中。to_h也不起作用

谢谢

更新22/07/2019:

感谢您的答复,我不得不稍作调整,因为puppet失败并出现“服务器错误:评估错误:评估方法调用时出错,'values'参数'hsh'期望哈希值,得到元组”

  $array_domain_jmsserver_addresses = 
  any2array(hiera('pdb_domain_msserver_addresses'))
  $array_domain_jmsserver_addresses.sort()
  $jms_subdeployments = lookup('jms_subdeployment_instances', $default_params)
  $hash_domain_jmsserver_addresses = Hash($array_domain_jmsserver_addresses)

  if $hash_domain_jmsserver_addresses.length > 0 {
      $jms_target_arg_tuples = $jms_subdeployments.keys.map |$subdep| {
      $jms_short_name = $subdep[0, 3]
      $jms_subdeployment_inst = regsubst(
          $hash_domain_jmsserver_addresses.values, /^/, "${jms_short_name}JMSServer_auto_")

  # the (key, value) tuple to which this element maps
  [ $subdep, { 'target' => $jms_subdeployment_inst } ]
}

$jms_target_args = Hash($jms_target_arg_tuples)
} else {
$jms_target_args = {}
}

notify{"Normal array is : ${jms_subdeployments}": }
notify{"Second array is : ${jms_target_args}": }  

$merge_subdeployment_targets = deep_merge($jms_subdeployments, $jms_target_args)
notify{"Merged array is : ${merge_subdeployment_targets}": }
  

正常值为:{BPMJMSModuleUDDs:BPMJMSSubDM => {确保=>存在,目标=> [BPMJMSServer_auto_1,BPMJMSServer_auto_server1],targettype => [JMSServer,JMSServer]},

     

第二个是:{BPMJMSModuleUDDs:BPMJMSSubDM => {target => [BPMJMSServer_auto_server2]}

     

合并为:{BPMJMSModuleUDDs:BPMJMSSubDM => {确保=>存在,目标=> [BPMJMSServer_auto_server2],目标类型=> [JMSServer,JMSServer]}

所需输出:

  

{BPMJMSModuleUDDs:BPMJMSSubDM => {确保=>存在,目标=> [BPMJMSServer_auto_1,BPMJMSServer_auto_server1,BPMJMSServer_auto_server2],targettype => [JMSServer,JMSServer,JMSServer]}

1 个答案:

答案 0 :(得分:0)

  

当我尝试deep_merge时,我发现.map输出为数组。

是的,这是its documented behaviorget_template_part()应该被认为是集合的 elements 上的函数,而不是整个集合,并且结果始终以数组的形式提供。

查看converting values to hashes的替代方法可能会很有用。特别吸引人的是:

  
      
  • 匹配map()的{​​{1}}被转换为哈希,其中每个元组都描述一个键/值条目
  •   

要使用此功能,请将每个条目映射到一个(键,值)元组,并将结果的元组数组转换为哈希。将您的尝试转换为这种方法可能看起来像这样:

Array

请注意,由于您没有使用Array[Tuple[Any,Any], 1]的值,因此我通过在其上应用if $array_domain_jmsserver_addresses.length > 0 { $jms_target_arg_tuples = $jms_subdeployments.keys.map |$subdep| { $jms_short_name = $subdep[0, 3] $jms_subdeployment_inst = regsubst( $array_domain_jmsserver_addresses.sort, /^/, "${jms_short_name}JMSServer_auto_") # the (key, value) tuple to which this element maps [ $subdep, { 'target' => $jms_subdeployment_inst } ] } $jms_target_args = Hash($jms_target_arg_tuples) } else { $jms_target_args = {} } $merge_subdeployment_targets = merge($jms_subdeployments, $jms_target_args) 函数来简化代码。我还使用$jms_subdeployments而不是keys()来根据regsubst()的元素形成目标名称,在这种情况下,我个人认为它们更易读,尤其是因为您没有使用索引。 / p>

我还推断出我认为您要完成的map()测试意味着什么,并将其替换为$array_domain_jmsserver_addresses数组长度的最外层测试。也可以通过构建散列而不考虑是否有目标,然后if defined()对其进行写操作,然后以某种更实用的形式编写它,但是这似乎是浪费的,因为似乎所有条目都将具有(相同)目标,否则将不会。