Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python API运行ansible playbook_Python_Ansible_Ansible Playbook - Fatal编程技术网

使用Python API运行ansible playbook

使用Python API运行ansible playbook,python,ansible,ansible-playbook,Python,Ansible,Ansible Playbook,如何用python脚本运行剧本?在python中使用ansible模块与以下内容的等效性是什么: ansible -i hosts dbservers -m setup ansible-playbook -i hosts -vvvv -k site.yml 我在中查看了他们的文档,但是他们的示例非常有限。您看到的是一些没有得到官方支持或建议的文档,因此几乎没有文档可供使用 这就是说,如果你真的想继续这门课程,我会先在bin中打开ansible剧本,然后反向工程你想做什么 弃用通知:此帖子自an

如何用python脚本运行剧本?在python中使用ansible模块与以下内容的等效性是什么:

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

我在中查看了他们的文档,但是他们的示例非常有限。

您看到的是一些没有得到官方支持或建议的文档,因此几乎没有文档可供使用

这就是说,如果你真的想继续这门课程,我会先在bin中打开ansible剧本,然后反向工程你想做什么

弃用通知:此帖子自ansible 2起不起作用。API已更改

“PythonAPI”中介绍了这一点

例如,
ansible-i hosts dbserver-m设置通过以下方式实现:

import ansible.runner

runner = ansible.runner.Runner(
   module_name='setup',
   module_args='',
   pattern='dbservers',
)
dbservers_get_facts = runner.run()
在Runner的
\uuuu init\uuuu
方法(来自
ansible.Runner
)中有一系列未记录的参数。有,但我已经在这篇文章中包括了一些参数,作为对你特别想要的东西的猜测

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'
)
对于剧本,请查看,这需要一组类似的初始值设定项:

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()
方法执行。e、 g:

from ansible.playbook import PlayBook
pb = PlayBook(playbook='/path/to/book.yml, --other initializers--)
pb.run()
在中可以找到更健壮的用法


据我所知,将剧本翻译成Python模块要复杂一些,但上面列出的文档应该会让您有所了解,您可以重用Ansible中内置的YAML解析器,将剧本转换成变量。

我已经回答了这个问题 在此处发布此内容是因为社区不鼓励发布链接。希望能有帮助

文档出人意料地缺乏,您必须开始

话虽如此,这是我拼凑的一个快速脚本,它成功地运行了一个剧本

#!/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()

只是一个在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()

根据《警戒者》的回答,我冒昧地将一个pkg上传到pypi,现在您可以使用这个简单的ansible runner:

只需pip安装并运行:


Ansible提供了可用于此目的的
Ansible runner
Python包(,)

使用示例来自:

导入ansible\u runner
r=ansible_runner.run(private_data_dir='/tmp/demo',playbook='test.yml')
打印(“{}:{}”。格式(r.status,r.rc))
#成功:0
对于r.events中的每个\u主机\u事件:
打印(每个主机事件['event'])
打印(“最终状态:”)
打印(r.stats)

这是不准确的,本手册涵盖了这一点。几乎没有文档这一事实是另一回事。特里斯坦:我不确定你在看什么,因为目前没有关于通过Python API运行剧本的官方文档。@Dolph点击--
ansible.runner
是运行剧本的入口点(见“Python API非常强大,这就是ansible CLI和ansible playbook的实现方式。”)。是的,对于已经在ansible代码库中工作过的人来说,文档读起来更好,但这并不能说明这个答案是正确的。现在有弃用警告(20200616_2215)。这似乎并没有回答如何运行playbook,而是一个单独的任务。还有一个
ansible.playbook.playbook
类,它还带有
run
方法,我想OP是在问这个问题-我知道这正是我试图找到的:Dansible.playbook.playbook调用runner执行(请参见ansible.runner中的
是游戏手册),但这一点很好。现在更新答案。非常感谢!在(其他地方?!)GitHub回购协议中也找到了一个很好的例子,其中包含了他们的--(编辑:哇,你已经指出了:D)@fideloper很乐意提供帮助。我扩展Ansible的典型途径是跳转到源代码中,或者直接启动pdb并遵循它——Ansible的代码库非常简单。我们如何为剧本获得所有相关的组变量?嗨,谢谢你的回答,帮了我很多,对于所有使用paramiko_ssh的人,请注意,你没有o让**
ssh\u common\u args=''
ssh\u extra\u args=''
非无**,否则您将得到一个异常:TypeError:sequence item:expected string,NoneType found花费我一点时间,并浏览代码以获得正确答案。对于Ansible 2.6(2.6.8)有API更改,您应该将Inventory更改为InventoryManager,以便…从ansible.Inventory.manager导入InventoryManager和Inventory=InventoryManager(loader=loader…variable\u manager.\u extra\u vars={'hosts':'mywebserver'}对于Ansible 2.8以上的版本,请参见伟大的答案。Ansible文档在这方面没有太大帮助,您的答案是我能找到的唯一实际工作的地方,谢谢!我们如何传递组变量文件?没关系;文件夹中没有包含它们;我在docker容器中运行
from ansible_playbook_runner import Runner

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