Ansible:将对象列表传递给python脚本

2024-10-08 18:23:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用script模块编写一个Ansible角色。脚本本身位于角色的files库中。环境变量test_var位于整个playbook的group_vars文件夹下的YAML文件中:

---
- name: execute script
  script: python_script.py {{ test_var }}
  args:
    executable: python

如果它只是一个简单的“key=value”类型的参数,那么它就可以很好地工作,但是我不确定如何将列表或对象列表之类的复杂项传递给python脚本以将其用作python字典。你知道吗

有没有最佳实践?你知道吗

上面的Ansible角色只返回列表的第一项。你知道吗

yaml输入:

test_var:
  - val:
      something: 1
  - other_val:
    - '1'
    - '2'
    - '3'

python代码:

import sys

i = 0

print('The first argument: ')
print sys.argv[1]
print(' ')

tmp_string = ""

print('Every argument printed out:')
for x in sys.argv:
  if i > 0:
    print x
    tmp_string += x
  i += 1

print(' ')
print('Concatenating together each argument:')
print tmp_string

结果:

changed: [localhost] => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to localhost closed.\r\n",
    "stderr_lines": [
        "Shared connection to localhost closed."
    ],
    "stdout": "The first argument: \r\n[{uval:\r\n \r\nEvery argument printed out:\r\n[{uval:\r\n{usomething:\r\n1}},\r\n{uother_val:\r\n[u1,\r\nu2,\r\nu3]}]\r\n \r\nConcatenateing together each argument:\r\n[{uval:{usomething:1}},{uother_val:[u1,u2,u3]}]\r\n",
    "stdout_lines": [
        "The first argument: ",
        "[{uval:",
        " ",
        "Every argument printed out:",
        "[{uval:",
        "{usomething:",
        "1}},",
        "{uother_val:",
        "[u1,",
        "u2,",
        "u3]}]",
        " ",
        "Concatenateing together each argument:",
        "[{uval:{usomething:1}},{uother_val:[u1,u2,u3]}]"
    ]
}

我不知道如何处理每行开头的u。你知道吗

正如我看到的,Ansible将yaml的每一行作为不同的命令行参数传递,因此第一行只包含第一行。我可以用for循环将它们连接成一个字符串,但我不知道如何将其转换成字典或python可以使用的东西。你知道吗


Tags: thetest角色列表varsysscriptval
2条回答

可能需要对变量应用filter。试试这个:

 -
- name: execute script
  script: python_script.py {{ test_var | to_yaml }}
  args:
    executable: python

Ansible并没有提供一个很好的机制来将复杂的数据传递给script模块。编写自己的Ansible模块,然后像其他模块一样将数据传递给Ansible模块可能更简单:

 -
- name: run my module
  mymodule:
    someparameter: "{{ test_var }}"

您的模块可以是一个Python脚本,在现有代码之上只有一个小样板。下面是一个非常简单的模板,可以支持上述示例:

#!/usr/bin/python

from __future__ import absolute_import, division, print_function  # NOQA

from ansible.module_utils.basic import AnsibleModule


def main():
    argument_spec = {
      'someparameter': dict(type='list', required=True),
    }

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True)

    result = {'changed': False}

    data = module.params['someparameter']

    # ...do something with your data here...

    module.exit_json(**result)


if __name__ == '__main__':
    main()

把你的模块放到你的角色所在的library目录中,你就一切就绪了。你知道吗

您可以在文档中找到更多信息:

相关问题 更多 >

    热门问题