ansible 通过循环控制对 dict 进行循环

问题描述 投票:0回答:1

我通过查找读取了 yml 文件并尝试循环字典。

yml 文件:

    ---
    root:
      children_one:
        attribute_one: true
        attribute_two: foo
      children_two:
        attribute_one: false
        attribute_two: bar
      children_three:
        attribute_one: false
        attribute_two: foo`

在 ansible 剧本中,当 attribute_one 为 false 时,我将打印出具有 attribute_two 的所有子项

    - ansible.builtin.debug:
        msg: "{{ item }} - {{ item.attribute_two }}"
      with_items: "{{ (lookup('template', 'file.yml.j2') | from_yaml).root }}"
      when: (item.attribute_one | lower) == 'false'

错误提示没有属性attribute_one。

我该如何解决?

谢谢

ansible yaml lookup
1个回答
0
投票

使用

with_dict
。这会将字典转换为列表。
attribute_one
的类型是布尔值。这简化了条件

    - debug:
        msg: "{{ item }}"
      with_dict: "{{ (lookup('template', 'file.yml') | from_yaml).root }}"
      when: not item.value.attribute_one

给予

skipping: [localhost] => (item={'key': 'children_one', 'value': {'attribute_one': True, 'attribute_two': 'foo'}}) 
ok: [localhost] => (item={'key': 'children_two', 'value': {'attribute_one': False, 'attribute_two': 'bar'}}) => 
  msg:
    key: children_two
    value:
      attribute_one: false
      attribute_two: bar
ok: [localhost] => (item={'key': 'children_three', 'value': {'attribute_one': False, 'attribute_two': 'foo`'}}) => 
  msg:
    key: children_three
    value:
      attribute_one: false
      attribute_two: foo`

使用

loop
和过滤器
dict2items

你会得到同样的效果
    - debug:
        msg: "{{ item }}"
      loop: "{{ (lookup('template', 'file.yml') | from_yaml).root |
                 dict2items }}"
      when: not item.value.attribute_one

这可以通过简化标签并拒绝管道中的

attribute_one
来进一步改进

    - debug:
        msg: "{{ item }}"
      loop: "{{ (lookup('template', 'file.yml') | from_yaml).root |
                dict2items |
                rejectattr('value.attribute_one') }}"
      loop_control:
        label: "{{ item.key }}"

给予

ok: [localhost] => (item=children_two) => 
  msg:
    key: children_two
    value:
      attribute_one: false
      attribute_two: bar
ok: [localhost] => (item=children_three) => 
  msg:
    key: children_three
    value:
      attribute_one: false
      attribute_two: foo`

用于测试的完整剧本示例

shell> cat file.yml 
---
root:
  children_one:
    attribute_one: true
    attribute_two: foo
  children_two:
    attribute_one: false
    attribute_two: bar
  children_three:
    attribute_one: false
    attribute_two: foo`
shell> cat pb.yml
- hosts: localhost

  tasks:

    - debug:
        msg: "{{ item }}"
      with_dict: "{{ (lookup('template', 'file.yml') | from_yaml).root }}"
      when: not item.value.attribute_one

    - debug:
        msg: "{{ item }}"
      loop: "{{ (lookup('template', 'file.yml') | from_yaml).root |
                 dict2items }}"
      when: not item.value.attribute_one

    - debug:
        msg: "{{ item }}"
      loop: "{{ (lookup('template', 'file.yml') | from_yaml).root |
                dict2items |
                rejectattr('value.attribute_one') }}"
      loop_control:
        label: "{{ item.key }}"
© www.soinside.com 2019 - 2024. All rights reserved.