39

如何在 python 脚本中运行剧本?在 python 中使用 ansible 模块相当于以下内容:

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

我在http://docs.ansible.com/developing_api.html查看他们的文档,但他们的例子非常有限。

4

6 回答 6

45

弃用通知:这篇文章在 ansible 2 中不起作用。API 已更改。

这包含在“Python API”下的Ansible 文档中。

例如,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()

__init__Runner的方法中有一堆未记录的参数(来自ansible.runner)。列出的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,
        ...
        ):

例如,上面指定 sudo 用户和 pass 的命令将是:

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'
)

对于剧本,请查看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,
        .... 

并且可以使用该.run()方法执行。例如:

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

更健壮的用法可以在ansible-playbook文件中找到。

据我所知,将 playbook 转换为 Python 模块会涉及更多内容,但上面列出的文档应该可以帮助您,您可以重用 Ansible 中内置的 YAML 解析器将 playbook 转换为变量。

于 2014-12-22T07:03:39.303 回答
26

只是一个适用于 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()
于 2019-08-14T20:57:02.120 回答
13

我已经回答了这个问题在这里 发布这个因为社区不鼓励发布链接。希望能帮助到你。

文档出奇地缺乏,您必须从这里开始

话虽如此,这是我一起编写的一个快速脚本,它可以运行一个剧本。

#!/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()
于 2016-02-21T16:58:34.403 回答
3

根据vigilander的回答,我冒昧地将 pkg 上传到 pypi,现在您可以使用这个简单的 ansible 跑步者:

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

from ansible_playbook_runner import Runner

Runner(['inventory_path'], 'playbook_path').run()
于 2020-09-17T14:10:53.867 回答
3

Ansible 提供了ansible-runnerPython 包(PyPIGitHub),可用于此目的。

文档中的用法示例:

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)
于 2020-10-08T09:13:38.817 回答
-17

您正在查看没有官方支持或推荐的内容,因此需要的文档很少。

也就是说,如果您真的想学习该课程,我将从在 bin 中打开 ansible-playbook 脚本并逆向工程您想要做的事情开始。

于 2014-12-22T06:46:12.407 回答