在ansible中合并嵌套字典

时间:2020-01-21 13:03:30

标签: dictionary ansible

我有2个不同的词典,其中包含我需要加入的应用程序信息。

landscape_dictionary:

{
  "app_1": {
    "Category": "application",
    "SolutionID": "194833",
    "Availability": null,
    "Environment": "stage",
    "Vendor/Manufacturer": null
  },
  "app_2": false
}

app_info_dictionary:

{
  "app_1": {
    "app_id": "6886817",
    "owner": "owner1@nomail.com",
    "prod": [
      "server1"
    ],
    "stage": []
  },
  "app_2": {
    "app_id": "3415012",
    "owner": "owner2@nomail.com",
    "prod": [
      "server2"
    ],
    "stage": [
      "server3"
    ]
  }
}

这是我用来连接两个字典的代码

- set_fact:
    uber_dict: "{{app_info_dictionary}}"

- set_fact:
    uber_dict: "{{ uber_dict | default ({}) | combine(new_item, recursive=true) }}"
  vars:
    new_item: "{ '{{item.key}}' : { 'landscape': '{{landscape_dictionary[item.key]|default(false)}}' } }"
  with_dict: "{{ uber_dict }}"

- debug:
    msg: "{{item.key}}: {{item.value}}"
  with_dict: "{{uber_dict}}"

如果landscape_dictionary中的值为false,则它将毫无问题地添加到uber_dict中。但是,如果该值包含信息,则它将失败。

这是错误:

fatal: [127.0.0.1]: FAILED! => {"msg": "|combine expects dictionaries, got u\"{ 'app_1' : { 'landscape': '{u'Category': u'application', u'SolutionID': u'194820', u'Availability': None, u'Environment': 'stage', u'Vendor/Manufacturer': None}' } }\""}

可能是什么问题?
在set_fact中设置var时是否需要进行额外的组合?

谢谢

1 个答案:

答案 0 :(得分:0)

此语法不合法,或者至少不符合您的想法:

new_item: "{ '{{item.key}}' : { 'landscape': '{{landscape_dictionary[item.key]|default(false)}}' } }"

最重要的是,ansible只会将 JSON 字符串自动强制转换为dict,但是您已经使用了 python 语法。

第二,动态构造dict的方法不是使用jinja2来构建文本,而是使用jinja2几乎是一种编程语言这一事实​​:

new_item: "{{
  {
    item.key: {
      'landscape': landscape_dictionary[item.key]|default(false)
    }
  }
}}"

每当您发现自己有嵌套的jinja2插值块时,这就是一种代码味道,您正像 text 那样过多地考虑该问题(嵌套,我的意思是{{ something {{nested}} else }})< / p>