【问题标题】:Flattening and filtering a complex structure in ansible - dict of list of dict扁平化和过滤 ansible 中的复杂结构 - dict 列表中的 dict
【发布时间】:2018-07-07 18:08:13
【问题描述】:

我有以这种方式表示的数据:

 {
    "key1": [{
      "name": "some name1",
      "index": "some idx1"
    },
    {
      "name": "some name2",
      "index": "some idx2"
    },
    {
      "name": "some name3",
      "index": "some idx3"
    }],
    "key2": [{
      "name": "some name4",
      "index": "some idx4"
    },
    {
      "name": "some name5",
      "index": "some idx5"
    },
    {
      "name": "some name6",
      "index": "some idx6"
    }]
}    

我想将上面的内容转换为这个,它基本上是一个字典,其中包含索引列表的现有键。

{ 
      "key1": [some idx1, some idx2, some idx3],
      "key2": [some idx4, some idx5, some idx6]
}

我已经看到了几个使用 map、extract 和 combine 的示例,但还不能完全使其工作。然而,我能够使用 jinja 来做到这一点,代码如下。 我的问题是,完成上述任务的最佳方法是什么。关于这种事情,推荐的最佳实践是什么 - 有什么理由不应该使用 jinja2 完成更复杂的操作(鉴于我见过的一个衬里过于复杂,其他人可能难以理解out - 因此使脚本难以维护)。

这里是解决问题的代码,但同样,不确定是否是实现此目的的最佳方法:

- hosts: local
  tags: test1
  gather_facts: False
  vars:
    dict1:
      key1:
        - { name: some name1, index: some idx1 }
        - { name: some name2, index: some idx2 }
        - { name: some name3, index: some idx3 }
      key2:
        - { name: some name4, index: some idx4 }
        - { name: some name5, index: some idx5 }
        - { name: some name6, index: some idx6 }
  tasks:      
  - name: "dict of list of dict"
    set_fact:
      index_map: |
        {% set map = dict() %}
        {% for k,v in dict1.iteritems() %}
          {% set x=map.__setitem__(k, []) %}
          {% for item in v %}
            {% set x= map[k].append(item.name) %}
          {% endfor %}
        {% endfor %}
        {{ map }}
  - debug: 
      msg: "{{ index_map }}"

为了扩展我试图解决的更多问题:给定一个“索引”,我想找到与之关联的键。我认为目标结构可以让我更容易地做到这一点。因此,索引列表的键字典或键索引的字典就足够了。

感谢您的建议..

【问题讨论】:

    标签: scripting ansible jinja2 devops


    【解决方案1】:

    Ansible 使用字典中的键的工具相当有限(请参阅this answer)。

    dictsort 过滤器有时会很方便,就像您的情况一样。
    它将dict转换为列表,您可以使用json_query对其进行处理。

    这是一个通过索引名称获取根键的任务:

    - debug:
        msg: "key is '{{ list_with_keys | json_query(qry) }}' for index {{ item }}"
      vars:
        list_with_keys: "{{ dict1 | dictsort | to_json | from_json }}"
        qry: "[?contains(([1] | [].index),`{{ item }}`)][] | [0]"
      with_items:
        - some idx5
        - some idx3
    

    dict1 取自您的示例。

    【讨论】:

      猜你喜欢
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-24
      • 1970-01-01
      • 1970-01-01
      • 2021-06-06
      相关资源
      最近更新 更多