使用 ansible/jinja2 将地图过滤器应用于字典的值

Apply map filter to value of dictionary with ansible/jinja2

我正在尝试编写一个 ansible 剧本,以一种格式良好的方式输出有关系统的一些详细信息。特别是磁盘大小。

输入变量类似于:

- friendly_name: 'disk1 name'
  size: 123456
- friendly_name: 'disk2 name'
  size: 654321
{{ dict(ansible_facts.disks | json_query('[].[friendly_name, size]')) }}

我正在努力想出一种方法将函数应用于字典的 'value'(或嵌套列表的第二个值,然后再将其转换为字典)-我我想申请 human_readable(unit='G') 或类似的,而不求助于 set_factFilterPlugins

所以理想情况下我会有一个输出变量的形式:

{'disk1 name': '1024G', 'disk2 name': '8192G'}

您可以将字典 ansible_facts.disks 拆分为两个列表,一个包含大小,另一个包含友好名称,然后将 human_readable 过滤器应用于包含带有 map filter, then zip 两个列表重新组合在一起。

给定任务:

- debug:
    msg: "{{ dict(
           ansible_facts.disks | map(attribute='friendly_name') | 
           zip(ansible_facts.disks | map(attribute='size') | map('human_readable','unit','G'))
         ) }}"
  vars:
    ansible_facts:
      disks:
        - friendly_name: 'disk1 name'
          size: 1099511627776
        - friendly_name: 'disk2 name'
          size: 8796093022208

这产生:

TASK [debug] ********************************************************************
ok: [localhost] => {
    "msg": {
        "disk1 name": "1024.00 Gb",
        "disk2 name": "8192.00 Gb"
    }
}

如果没有格式,您可以简单地使用 items2dict


    - debug:
        msg: "{{ ansible_facts.disks|items2dict(key_name='friendly_name',
                                                value_name='size') }}"

给予

  msg:
    disk1 name: 1099511627776
    disk2 name: 8796093022208

使用 Jinja 更改格式,例如

    - debug:
        msg: "{{ _disks|from_yaml }}"
      vars:
        _disks: |
          {% for i in ansible_facts_disks %}
          {{ i.friendly_name }}: {{ i.size|human_readable(unit='G') }}
          {% endfor %}

给予

  msg:
    disk1 name: 1024.00 GB
    disk2 name: 8192.00 GB