简体   繁体   English

使用 Python API 运行 ansible-playbook

[英]Running ansible-playbook using Python API

How can I run a playbook in python script?如何在 python 脚本中运行剧本? What is the equivalent of the following using ansible module in python:在 python 中使用 ansible 模块的等价物是什么:

ansible -i hosts dbservers -m setup
ansible-playbook -i hosts -vvvv -k site.yml

I was looking at their documenation in http://docs.ansible.com/developing_api.html but they have very limited examples.我在http://docs.ansible.com/developing_api.html查看他们的文档,但他们的例子非常有限。

Deprecation Notice: This post doesn't work as of ansible 2. The API was changed.弃用通知:这篇文章从 ansible 2 开始不起作用。API 已更改。

This covered in the Ansible documentation under "Python API."这在“Python API”下的Ansible 文档有所介绍

For example, ansible -i hosts dbservers -m setup is implemented via:例如, ansible -i hosts dbservers -m setup是通过以下方式实现的:

import ansible.runner

runner = ansible.runner.Runner(
   module_name='setup',
   module_args='',
   pattern='dbservers',
)
dbservers_get_facts = runner.run()

There are a bunch of non-documented parameters in the __init__ method of Runner (from ansible.runner ). Runner 的__init__方法中有一堆未记录的参数(来自ansible.runner )。 There's too many to list inline , but I've included some of the parameters in this post as a guess to what you're specifically looking for.太多内容无法列出 inline ,但我在这篇文章中包含了一些参数,作为对您具体要查找的内容的猜测。

class Runner(object):
    ''' core API interface to ansible '''

    # see bin/ansible for how this is used...

    def __init__(self,
        host_list=C.DEFAULT_HOST_LIST,      # ex: /etc/ansible/hosts, legacy usage
        module_path=None,                   # ex: /usr/share/ansible
        module_name=C.DEFAULT_MODULE_NAME,  # ex: copy
        module_args=C.DEFAULT_MODULE_ARGS,  # ex: "src=/tmp/a dest=/tmp/b"
        ...
        pattern=C.DEFAULT_PATTERN,          # which hosts?  ex: 'all', 'acme.example.org'
        remote_user=C.DEFAULT_REMOTE_USER,  # ex: 'username'
        remote_pass=C.DEFAULT_REMOTE_PASS,  # ex: 'password123' or None if using key
        remote_port=None,                   # if SSH on different ports
        private_key_file=C.DEFAULT_PRIVATE_KEY_FILE, # if not using keys/passwords
        sudo_pass=C.DEFAULT_SUDO_PASS,      # ex: 'password123' or None
        ...
        sudo=False,                         # whether to run sudo or not
        sudo_user=C.DEFAULT_SUDO_USER,      # ex: 'root'
        module_vars=None,                   # a playbooks internals thing
        play_vars=None,                     #
        play_file_vars=None,                #
        role_vars=None,                     #
        role_params=None,                   #
        default_vars=None,                  #
        extra_vars=None,                    # extra vars specified with he playbook(s)
        is_playbook=False,                  # running from playbook or not?
        inventory=None,                     # reference to Inventory object
        ...
        su=False,                           # Are we running our command via su?
        su_user=None,                       # User to su to when running command, ex: 'root'
        su_pass=C.DEFAULT_SU_PASS,
        vault_pass=None,
        ...
        ):

For instance, the above command that specifies a sudo user and pass would be:例如,上面指定 sudo 用户和密码的命令是:

runner = ansible.runner.Runner(
   module_name='setup',
   module_args='',
   pattern='dbservers',
   remote_user='some_user'
   remote_pass='some_pass_or_python_expression_that_returns_a_string'
)

For playbooks, look into playbook.PlayBook , which takes a similar set of initializers:对于剧本,请查看playbook.PlayBook ,它采用一组类似的初始化程序:

class PlayBook(object):
    '''
    runs an ansible playbook, given as a datastructure or YAML filename.
    ...
    '''

    # *****************************************************

    def __init__(self,
        playbook         = None,
        host_list        = C.DEFAULT_HOST_LIST,
        module_path      = None,
        .... 

and can be executed with the .run() method.并且可以使用.run()方法执行。 eg:例如:

from ansible.playbook import PlayBook
pb = PlayBook(playbook='/path/to/book.yml, --other initializers--)
pb.run()

more robust usage can be found in the ansible-playbook file .更强大的用法可以在ansible-playbook文件中找到

As far as I know, translating playbooks to Python modules is a bit more involved, but the documentation listed above should get you covered and you can reuse the YAML parser built into Ansible to convert playbooks to variables.据我所知,将 playbook 转换为 Python 模块要复杂一些,但是上面列出的文档应该可以帮助您了解,您可以重用 Ansible 中内置的 YAML 解析器将 playbook 转换为变量。

Just a quick code update that works on 2.8.3,只是一个适用于 2.8.3 的快速代码更新,

from ansible import context
from ansible.cli import CLI
from ansible.module_utils.common.collections import ImmutableDict
from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.parsing.dataloader import DataLoader
from ansible.inventory.manager import InventoryManager
from ansible.vars.manager import VariableManager

loader = DataLoader()

context.CLIARGS = ImmutableDict(tags={}, listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh',
                    module_path=None, forks=100, remote_user='xxx', private_key_file=None,
                    ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=True,
                    become_method='sudo', become_user='root', verbosity=True, check=False, start_at_task=None)

inventory = InventoryManager(loader=loader, sources=('/xxx/inventory_file',))

variable_manager = VariableManager(loader=loader, inventory=inventory, version_info=CLI.version_info(gitinfo=False))

pbex = PlaybookExecutor(playbooks=['/xxx/playbook.yml'], inventory=inventory, variable_manager=variable_manager, loader=loader, passwords={})

results = pbex.run()

I have answered the question here Posting this here cause posting links is discouraged in the community.我已经在这里回答了这个问题在这里发布这个是因为社区不鼓励发布链接。 Hope it helps.希望能帮助到你。

The documentation is surprisingly lacking and you'll have to get started here该文档令人惊讶地缺乏,您必须从这里开始

That being said, here is a quick script I hacked together that manages to run a playbook.话虽如此,这是我编写的一个快速脚本,可以运行剧本。

#!/usr/bin/env python

import os
import sys
from collections import namedtuple

from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import Inventory
from ansible.executor.playbook_executor import PlaybookExecutor

loader = DataLoader()

inventory = Inventory(loader=loader, sources='/home/slotlocker/hosts2')
variable_manager = VariableManager(loader=loader, inventory=inventory)
playbook_path = '/home/slotlocker/ls.yml'

if not os.path.exists(playbook_path):
    print '[INFO] The playbook does not exist'
    sys.exit()

Options = namedtuple('Options', ['listtags', 'listtasks', 'listhosts', 'syntax', 'connection','module_path', 'forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check','diff'])
options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh', module_path=None, forks=100, remote_user='slotlocker', private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=True, become_method='sudo', become_user='root', verbosity=None, check=False, diff=False)

variable_manager.extra_vars = {'hosts': 'mywebserver'} # This can accomodate various other command line arguments.`

passwords = {}

pbex = PlaybookExecutor(playbooks=[playbook_path], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords)

results = pbex.run()

Ansible provides the ansible-runner Python package ( PyPI , GitHub ), which can be used for this. Ansible 提供了 ansible ansible-runner Python 包( PyPIGitHub ),可用于此目的。

Usage example from the documentation : 文档中的用法示例:

import ansible_runner
r = ansible_runner.run(private_data_dir='/tmp/demo', playbook='test.yml')
print("{}: {}".format(r.status, r.rc))
# successful: 0
for each_host_event in r.events:
    print(each_host_event['event'])
print("Final status:")
print(r.stats)

Based on vigilander 's answer, I took the liberty to upload a pkg to pypi and now you can use this simple ansible runner:根据vigilander的回答,我冒昧地将 pkg 上传到 pypi,现在您可以使用这个简单的 ansible runner:

Just pip install ansible-playbook-runner and run:只需 pip install ansible-playbook-runner并运行:

from ansible_playbook_runner import Runner

Runner(['inventory_path'], 'playbook_path').run()

You're looking at something that isn't officially supported or recommended therefore little documentation to be had.您正在查看不受官方支持或推荐的内容,因此几乎没有文档。

That said, if you really want to pursue that course I would start with cracking open the ansible-playbook script in bin and reverse engineering what you want to do.也就是说,如果你真的想学习这门课程,我会首先打开 bin 中的 ansible-playbook 脚本并对你想做的事情进行逆向工程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM