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
我看到过类似的问题,但有些地方不合我意。
我有一个我编写的自定义模块,它解析来自 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