在 Ansible 中将 Python 脚本的输出转换为 dict [英] Converting output of Python script to dict in Ansible

查看:20
本文介绍了在 Ansible 中将 Python 脚本的输出转换为 dict的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 test.py 的 Python 脚本,它是:

I have a Python script called test.py which is:

#!/usr/bin/python
a = "A:2\nB:5"
print a

现在在我的 Ansible 剧本中,我正在运行此脚本并使用此任务将输出注册到变量

Now in my Ansible playbook, I am running this script and registering the output to a variable using this task

- name: Create variable from the command
  command: "python ./test.py"
  register: command_output

我想在 ansible 中将输出转换为字典 Dict,以便在后续任务中我可以访问像 Dict.ADict.B<这样的值/代码>.

I want to convert the output to a dictionary Dict in ansible so that in subsequent tasks I can access values like Dict.A or Dict.B.

我尝试了这里的所有选项 但没有一个对我有用.

I tried all the options present here but none are working for me.

在实现第一个答案时,这是我的剧本:

While implementing the first answer this is my playbook:

---
- hosts: localhost
  gather_facts: no
  become: yes
  tasks:
    - name: Create variable from command
      command: "python ./test.py"
      register: command_output

    - name: set parameter values as fact
      set_fact:
        parameter: >
          "{{ parameter | default({}) | combine ( { item.split(':')[0]: item.split(':')[1] } ) }}"
      with_items: "{{command_output.stdout_lines}}"

    - debug:
        msg: "{{parameter}}"

为此,我收到错误:

TASK [set parameter values as fact] **************************************************************************************************************************************************************
ok: [localhost] => (item=A:2)
fatal: [localhost]: FAILED! => {"msg": "|combine expects dictionaries, got u'\"{u\\'A\\': u\\'2\\'}\"\\n'"}

对于第二个答案,我写了这个脚本

For second answer I wrote this script

---
- hosts: localhost
  gather_facts: no
  become: yes
  tasks:

    - name: Create variable from command
      command: "python ./test.py"
      register: command_output


    - name: set parameter values as fact
      set_fact:
        parameter: >
          {{
            parameter | default({})|
            combine(
              dict([item.partition(':')[::2]|map('trim')])
            )
          }}
      with_items: "{{command_output.stdout_lines}}"

    - debug:
        msg: "{{parameter.B}}"

在这种情况下,我收到此错误

In this case, I am getting this error

fatal: [localhost]: FAILED! => {"msg": "Unexpected templating type error occurred on ({{ dict([item.partition(':')[::2]|map('trim')]) }}): <lambda>() takes exactly 0 arguments (1 given)"}

我不知道如何将我的 python 脚本的输出转换为 Ansible 中的字典.我可以将输出作为列表、字符串或字典本身从 python 发送,但无论如何,它在 Ansible 中注册为字符串,之后,我无法在 Ansible 中将其转换回字典.

I am clueless what I can do to convert the output of my python script to a dictionary in Ansible. I can send the output as the list, string or dictionary itself from python but in any case, it registers as a string in Ansible and after that, I am not able to convert it back to the dictionary in Ansible.

如果有任何其他方法可以实现这一点,请帮助.我正在考虑为此编写 ansible 模块,但即使在那里我也不确定 ansible 将如何处理模块的输出,因为本质上它也是一个 python 脚本.

If there is any other way to implement this please help. I am thinking about writing ansible module for this but even there I am not sure how will ansible handle the output of module as in essence that is also a python script.

推荐答案

说明

这是 YAML 解释的问题.您在块标量定义 > 之后使用 " 显式定义一个字符串,这意味着在第一次迭代后 parameter 变量被定义为字符串.

This is a problem with YAML interpretation. You explicitly define a string with " following block scalar definition > which means after the first iteration parameter variable is defined as string.

然后第二次迭代失败,因为您将该字符串传递给 combine 过滤器(而不是它期望的字典).

Then the second iteration fails, because you pass that string to the combine filter (instead of a dictionary, which it expects).

解决方案

要么将其写在一行中,而不是使用 YAML 块标量定义(>):

Either write this in a single line instead of using YAML block scalar definition (>):

parameter: "{{ parameter | default({}) | combine ( { item.split(':')[0]: item.split(':')[1] } ) }}"

或者去掉引号:

parameter: >
  {{ parameter | default({}) | combine ( { item.split(':')[0]: item.split(':')[1] } ) }}

输出:

TASK [Create variable from the command] *************************************************************************************
changed: [localhost]

TASK [set parameter values as fact] *****************************************************************************************
ok: [localhost] => (item=A:2)
ok: [localhost] => (item=B:5)

TASK [debug] ****************************************************************************************************************
ok: [localhost] => {
    "msg": {
        "A": "2",
        "B": "5"
    }
}

这篇关于在 Ansible 中将 Python 脚本的输出转换为 dict的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆