Ansible更新嵌套列表

Ansible updating nested list

我正在处理一个 ansible 任务,将更新列表中的嵌套列表。 输入:

- name: test array of objects
  set_fact:
    list: 
       - name: x1
         surname: y1
         childrens: 
            - children1
            - children2
       - name: x2
         surname: y2
         childrens: 
            - children3
            - children4

例如,我想添加新的children到/删除现有的children from the object with params

name: x1
surname: y1

示例输出(已添加 children):

- name: test array of objects
  set_fact:
    list: 
       - name: x1
         surname: y1
         childrens: 
            - children1
            - children2
            - children3
       - name: x2
         surname: y2
         childrens: 
            - children3
            - children4

该任务将处理 1000 多条记录,应该可以高效地完成。

谢谢!

添加索引。例如 全名

    - set_fact:
        list: "{{ _list|from_yaml }}"
      vars:
        _list: |
          {% for i in range(3) %}
          - name: x{{ i }}
            surname: y{{ i }}
            fullname: x{{ i }}_y{{ i }}
            index: {{ i }}
            childrens:
              - children1
              - children2
          {% endfor %}

给予

  list:
    - childrens: [children1, children2]
      fullname: x0_y0
      index: 0
      name: x0
      surname: y0
    - childrens: [children1, children2]
      fullname: x1_y1
      index: 1
      name: x1
      surname: y1
    - childrens: [children1, children2]
      fullname: x2_y2
      index: 2
      name: x2
      surname: y2

然后将列表转换为字典,例如

    - set_fact:
        dict: "{{ list|items2dict(key_name='fullname', value_name='childrens') }}"

给予

  dict:
    x0_y0: [children1, children2]
    x1_y1: [children1, children2]
    x2_y2: [children1, children2]

更新字典的条目,例如

    - set_fact:
        dict: "{{ dict|combine({item.fullname: _children}) }}"
      loop:
        - {fullname: x1_y1, add: [children3]}
      vars:
        _children: "{{ dict[item.fullname] + item.add }}"

给予

  dict:
    x0_y0: [children1, children2]
    x1_y1: [children1, children2, children3]
    x2_y2: [children1, children2]

从字典中恢复列表

    - set_fact:
        list2: "{{ dict|dict2items(key_name='fullname', value_name='childrens') }}"

给予

  list2:
    - childrens: [children1, children2]
      fullname: x0_y0
    - childrens: [children1, children2, children3]
      fullname: x1_y1
    - childrens: [children1, children2]
      fullname: x2_y2

这样,只需几秒钟即可创建 1000 个项目并更新其中的几个。例如


    - set_fact:
        list: "{{ _list|from_yaml }}"
      vars:
        _list: |
          {% for i in range(1000) %}
      ...

    - set_fact:
        dict: "{{ dict|combine({item.fullname: _children}) }}"
      loop:
        - {fullname: x101_y101, add: [children3]}
        - {fullname: x301_y301, add: [children3]}
        - {fullname: x501_y501, add: [children3]}
      ...

    - debug:
        msg: |
          {{ list2.100 }}
          {{ list2.101 }}
          {{ list2.102 }}
          {{ list2|length }}

给予

  msg: |-
    {'fullname': 'x100_y100', 'childrens': ['children1', 'children2']}
    {'fullname': 'x101_y101', 'childrens': ['children1', 'children2', 'children3']}
    {'fullname': 'x102_y102', 'childrens': ['children1', 'children2']}
    1000

使用lists_mergeby合并所有项目,例如

    - set_fact:
        list3: "{{ list|
                   community.general.lists_mergeby(list2, 'fullname')|
                   sort(attribute='index') }}"