如何使用子流程运行Ansible剧本

时间:2019-09-02 22:03:14

标签: python ansible subprocess

我是ansible的新手,无论我尝试什么,都无法通过python脚本调用简单的剧本。

代码示例:

import subprocess


def sample(host, user):
    cmd = ["ansible-playbook",
           "-i {},".format(host),
           "-e ansible_user={}".format(user),
           "sample.yml",
           "-v"]

    subprocess.run(cmd)


def main():
    sample("hostname,", "user")


if __name__ == '__main__':
    main()

STDOUT示例:

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************

在我终止脚本之前,脚本一直保持这样。

从命令行$ ansible-playbook sample.yml -i "hostname," -e "user=user"执行Ansible剧本时,我得到了预期的STDOUT:

PLAY [all] **********************************************************************************************************************************************************************************************************************************

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

TASK [debug] ********************************************************************************************************************************************************************************************************************************
ok: [hostname] => {
    "msg": "I'm on hostname"
}

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
hostname              : ok=2    changed=0    unreachable=0    failed=0

我的目标是用一个主机覆盖这些组,这就是为什么我使用语法-i "hostname,"

sample.yml文件的示例:

---
- hosts: all
  remote_user: '{{ ansible_user }}'
  any_errors_fatal: true
  tasks:
    - debug:
        msg: "I'm on {{ ansible_host }}"

我哪里错了?

2 个答案:

答案 0 :(得分:0)

缺少命令行参数的传递。参见sys.argv。其余代码很好。

from sys import argv
import subprocess
[...]

def main():
    script, hostname, user = argv
    sample(hostname, user)
[...]

注释

1)要测试剧本,额外的参数应为 ansible_user

$ ansible-playbook sample.yml -i "hostname," -e "ansible_user=user"

2)使用sample("hostname,", "user")时,剧本始终以"hostname"的身份在"user"运行

3)可以使用-l代替-i并避免昏迷

$ ansible-playbook sample.yml -l "hostname" -e "ansible_user=user"

4)看一下Ansible Runner

答案 1 :(得分:0)

因此使它同时适用于WSL和LinuxOS的唯一因素是:

#!/usr/bin/python3

import pprint
import subprocess
import sys


def sample(host, user):
    cmd = ["ansible-playbook",
           "-i {},".format(host),
           "-e ansible_user={}".format(user),
           "-e ANSIBLE_HOST_KEY_CHECKING=False",
           "sample.yml",
           "-v"]

    proc = subprocess.Popen(cmd,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            )

    try:
        outs, errs = proc.communicate(timeout=15)
        pprint.pprint(outs.decode().split('\n'))
    except subprocess.SubprocessError as errs:
        proc.kill()
        sys.exit("Error: {}".format(errs))

def main():
    sample("hostname", "user")


if __name__ == '__main__':
    main()

您可以简单地将其执行为:

$ python3 test.py
['Using /etc/ansible/ansible.cfg as config file',
 '',
 'PLAY [all] '
 '*********************************************************************',
 '',
 'TASK [Gathering Facts] '
 '*********************************************************',
 'ok: [hostname]',
 '',
 'TASK [debug] '
 '*******************************************************************',
 'ok: [hostname] => {',
 '    "msg": "I\'m on hostname"',
 '}',
 '',
 'PLAY RECAP '
 '*********************************************************************',
 'hostname              : ok=2    changed=0    unreachable=0    '
 'failed=0   ',
 '',
 '']

更新:如果您想与Python2和Python3兼容,则需要将代码最小化:

import pprint
import subprocess
import sys


def sample(host, user):
    cmd = ["ansible-playbook",
           "-i {},".format(host),
           "-e ansible_user={}".format(user),
           "-e ANSIBLE_HOST_KEY_CHECKING=False",
           "sample.yml",
           "-v"]

    proc = subprocess.Popen(cmd,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            )

    try:
        if sys.version_info > (3, 0):
            # Python 3 code in this block
            outs, errs = proc.communicate(timeout=15)
            pprint.pprint(outs.decode().split('\n'))
        else:
            # Python 2 code in this block
            outs, errs = proc.communicate()
            pprint.pprint(outs.decode().split('\n'))
    except subprocess.SubprocessError as errs:
        proc.kill()
        sys.exit("Error: {}".format(errs))


def main():
    sample("hostname", "user")


if __name__ == '__main__':
    main()

然后,您可以使用以下命令进行测试:

$ python test.py
['Using /etc/ansible/ansible.cfg as config file',
 '',
 'PLAY [all] *********************************************************************',
 '',
 'TASK [Gathering Facts] *********************************************************',
 'ok: [hostname]',
 '',
 'TASK [debug] *******************************************************************',
 'ok: [hostname] => {',
 '    "msg": "I\'m on hostname"',
 '}',
 '',
 'PLAY RECAP *********************************************************************',
 'hostname              : ok=2    changed=0    unreachable=0    failed=0   ',
 '',
 '']

仅适用于Python3:

$ python3 test.py
['Using /etc/ansible/ansible.cfg as config file',
 '',
 'PLAY [all] '
 '*********************************************************************',
 '',
 'TASK [Gathering Facts] '
 '*********************************************************',
 'ok: [hostname]',
 '',
 'TASK [debug] '
 '*******************************************************************',
 'ok: [hostname] => {',
 '    "msg": "I\'m on hostname"',
 '}',
 '',
 'PLAY RECAP '
 '*********************************************************************',
 'hostname              : ok=2    changed=0    unreachable=0    '
 'failed=0   ',
 '',
 '']
````

One problem that I have noticed here a minor problem is that [pycharm][1] installed on WindowsOS and running with Python2/3 2/3 Ubuntu wsl://UBUNTU/usr/bin/python is unfortunately stays frozen as shown above, but if you execute the code from terminal everything works as expected.

I have installed WSL not WSL2 maybe this problem is fixed on WSL2.


  [1]: https://www.jetbrains.com/pycharm/