【问题标题】:Ansible use return value as dictionaryAnsible 使用返回值作为字典
【发布时间】:2018-08-15 16:03:50
【问题描述】:

我看到了类似的问题,但我没有点击。

我编写了一个自定义模块,它解析来自 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 对象”没有属性“名称”

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

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

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

谢谢!

【问题讨论】:

    标签: python ansible ansible-facts


    【解决方案1】:

    您的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
    

    库/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
    

    【讨论】:

    • 这段代码在哪个 Ansible 版本上运行正确?
    • 我使用 ansible-playbook 2.6.0 成功测试了这个
    • 在 2.9.18 我得到以下信息:ERROR! conflicting action statements: debug, var,但使用 - debug: var=DEVICE_RESULT 它可以工作。
    猜你喜欢
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 2021-12-04
    相关资源
    最近更新 更多