Ansible 使用 return 值作为字典

Ansible use return value as dictionary

我看到过类似的问题,但有些地方不合我意。

我有一个我编写的自定义模块,它解析来自 API 的数据,我想将该模块的结果用作我的剧本中的字典(供后续任务引用)。

获得数据后,我将使用如下模块:

- name: build ditionary of system ip's
  device_vars_builder:
    DEV_OUT: "{{ DEVICE_LIST }}"
  register: DEVICE_RESULT

DEVICE_RESULT.msg_output 上的调试如下所示:

ok: [localhost] => {
    "msg": [
        "{ name: 'TEST1_HOST', ip_addr: '1.1.1.1' }", 
        "{ name: 'TEST2_HOST', ip_addr: '1.1.1.2' }"
    ]
}

但是如果我使用 Loop 或

- name: iterate items
  debug:
    msg: '{{ item.name }}'
  with_items: DEVICE_RESULT.msg_output

我得到一个错误 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' 没有属性 'name'

我还尝试使用 set_fact 转换结果,认为它没有被识别为字典:

- name: Populate dictionary with items
  set_fact:
    DEVICE_DATA: "{{ DEVICE_DATA|default([]) +  [ item ] }}"
  with_items: "{{ DEVICE_RESULT.msg_output }}"

有人对我如何将结果用作字典有任何建议吗?使用 python 脚本,我可以根据需要使输出尽可能友好。

谢谢!

您的with_items缺少扩展:

- name: iterate items
  debug:
    msg: "{{ item.name }}"
  with_items: DEVICE_RESULT.msg_output

应该是:

- name: iterate items
  debug:
    msg: "{{ item.name }}"
  with_items: "{{ DEVICE_RESULT.msg_output }}"

下面是一个使用 Python 3.6.4 和 Ansible 2.6.0 的工作示例:

play.yml

---

- hosts: localhost
  tasks:
    - name: build dictionary of system ips
      custommod:
      register: DEVICE_RESULT

    - debug:
        var: DEVICE_RESULT

    - name: iterate items
      debug:
        msg: "{{ item.name }}"  # You need double quotes here
      with_items: "{{ DEVICE_RESULT.msg }}"  # And double quotes here

library/custommod.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
from ansible.module_utils.basic import *


def main():
    module = AnsibleModule({})
    l = [
            { 'name': 'TEST1_HOST', 'ip_addr': '1.1.1.1' },
            { 'name': 'TEST2_HOST', 'ip_addr': '1.1.1.2' },
        ]

    module.exit_json(changed=True, msg=l)


if __name__ == '__main__':
    main()

输出

ansible-playbook play.yml
 [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source

 [WARNING]: No inventory was parsed, only implicit localhost is available

 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'


PLAY [localhost] *******************************************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************************************
ok: [localhost]

TASK [build ditionary of system ip's] **********************************************************************************************************************************************
changed: [localhost]

TASK [debug] ***********************************************************************************************************************************************************************
ok: [localhost] => {
    "DEVICE_RESULT": {
        "changed": true,
        "failed": false,
        "msg": [
            {
                "ip_addr": "1.1.1.1",
                "name": "TEST1_HOST"
            },
            {
                "ip_addr": "1.1.1.2",
                "name": "TEST2_HOST"
            }
        ]
    }
}

TASK [iterate items] ***************************************************************************************************************************************************************
ok: [localhost] => (item={'name': 'TEST1_HOST', 'ip_addr': '1.1.1.1'}) => {
    "msg": "TEST1_HOST"
}
ok: [localhost] => (item={'name': 'TEST2_HOST', 'ip_addr': '1.1.1.2'}) => {
    "msg": "TEST2_HOST"
}

PLAY RECAP *************************************************************************************************************************************************************************
localhost                  : ok=4    changed=1    unreachable=0    failed=0