【问题标题】:Ansible selectattr + map + list returns empty resultAnsible selectattr + map + list 返回空结果
【发布时间】:2019-01-23 19:56:29
【问题描述】:

我已经阅读和搜索了很多,但无法解决这个问题。你能帮忙吗?

使用下面的内容,我需要提取属性“ipAddress”并推送到一个列表。实际数据是对象的字典,例如“host01”,但对于示例,我将数据减少到一个主机。

    {
        "host01": {
            "fqdn": "host01.mydomain",
            "interface": {
                "Bundle-Ether1001": {
                    "ipAddress": "10.20.30.41",
                    "subnetMask": "255.255.255.252"
                },
                "Bundle-Ether1002": {
                    "ipAddress": "10.20.30.45",
                    "subnetMask": "255.255.255.252"
                }
            },
            "timestamp": 1545420334
        }
}

我的剧本如下:

---
- name : myplaybook 
  hosts: localhost
  vars:
    myjson: "{{ lookup('file', 'api.json') | from_json }}"


  tasks:
    - name: debug
      debug:
        msg: "{{myjson}}"

    - name: debugallip
      when: item.value.interface is defined
      debug:
        msg: "{{ item | selectattr('ipAddress', 'defined') | map('value.ipAddress') | list }}"
      with_dict: "{{ myjson }}"

返回一个空列表? :(

任务 [调试] ******************************************* *********************************************** ok: [localhost] => (item={'value': {u'interface': {u'Bundle-Ether1001': {u'subnetMask': u'255.255.255.252', u'ipAddress': u'10.20 .30.41'}, u'Bundle-Ether1002': {u'subnetMask': u'255.255.255.252', u'ipAddress': u'10.20.30.45'}}, u'timestamp': 1545420334, u'fqdn' : u'host01.mydomain'}, 'key': u'host01'}) => { “味精”:[] }

我做错了什么??

【问题讨论】:

    标签: loops dictionary filter ansible


    【解决方案1】:

    selectattr 过滤器不正确,因为 ipAddress 隐藏在结构中,而不是在您的特定设置中的顶层......好吧,任何东西。在任务输出中可以很容易地看到item 的形状,所以我不知道为什么你会假设任何其他形状,但我们在这里。您对map 的调用也不正确,因为没有像value.ipAddress 这样的过滤器,只有在您的selectattr 正确时才会真正爆炸。

    - debug:
        msg: '{{ item.value.interface | dict2items | map(attribute="value.ipAddress") | select("defined") }}'
      with_dict: '{{ myjson }}'
    

    如果您希望将所有 ipAddress 值隐藏在 host.interface 结构中,则基本上需要在 host.interface 字典上执行 另一个 with_dict 循环,这就是 @ 987654332@ 可以。然后,您可以通过继续提取 .ipAddress 来节省一些复制面食,但有未定义的风险,然后在最后扔掉未定义的内容

    【讨论】:

    • 感谢 cmets,我想不知何故我不会接受 json 对象列表实际上是一个数组。您是否建议我的数据结构格式不正确?如果是这样,我想学习,如果您有建议,我愿意接受。最后,感谢您的解释并为我提供了一个工作示例。我将以此为基础。
    • 事实上,我非常想知道如何在循环中循环(嵌套循环?)我试过了,哦,我试过了......我只是没看到。我有没有提到我使用 Ansible 不到一个月?
    【解决方案2】:

    一个选项是使用 json_query

    - debug:
        msg: "{{ item.value.interface | dict2items | json_query('[].value.ipAddress') }}"
    

    【讨论】:

    • 嗨弗拉基米尔,好吧,我也试过这个,我认为它很难看,但至少它对我有用。我的解决方案将生成一个列表列表,并通过一些额外的步骤,我终于可以得到一些可以使用的东西。这是我的 mylist: "{{ mylist + [item | json_query('value.interface.*.ipAddress')] }}" with_dict: "{{ myjson }}" 在查看了您的解决方案和 Matthew 的解决方案之后,它变得清晰了对我来说,我必须将接口列表视为一个数组......
    • mylist: "{{ mylist + [item | json_query('value.interface.*.ipAddress')] }}" with_dict: "{{ myjson }}"
    猜你喜欢
    • 2016-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多