最近想利用python来调用anbile来实现一些功能,发现ansible的api已经升级到了2.0,使用上比以前复杂了许多。
这里我参考了官方文档的例子,做了一些整改,写了一个python调用ansible的函数,执行过程中输出执行结果。函数返回执行结果,便于筛选和存储所需的数据:
# vim exec_ansible.py def exec_ansible(module,args,host): import json from collections import namedtuple from ansible.parsing.dataloader import DataLoader from ansible.vars import VariableManager from ansible.inventory import Inventory from ansible.playbook.play import Play from ansible.executor.task_queue_manager import TaskQueueManager from ansible.plugins.callback import CallbackBase class ResultCallback(CallbackBase): def v2_runner_on_ok(self, result, **kwargs): host = result._host self.data = json.dumps({host.name: result._result}, indent=4) print(self.data) Options = namedtuple(‘Options‘, [‘connection‘, ‘module_path‘, ‘forks‘, ‘become‘, ‘become_method‘, ‘become_user‘, ‘check‘]) # initialize needed objects variable_manager = VariableManager() loader = DataLoader() #module_path参数指定本地ansible模块包的路径 options = Options(connection=‘smart‘, module_path=‘/usr/local/lib/python3.5/site-packages/ansible/modules/‘, forks=100, become=None, become_method=None, become_user=‘root‘, check=False) passwords = dict(vault_pass=‘secret‘) # Instantiate our ResultCallback for handling results as they come in results_callback = ResultCallback() # create inventory and pass to var manager #host_list指定本地ansible的hosts文件 inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=‘/etc/ansible/hosts‘) variable_manager.set_inventory(inventory) # create play with tasks play_source = dict( name = "Ansible Play", #hosts可以指定inventory中的一组主机,也可指定单台主机 hosts = host, gather_facts = ‘no‘, #task执行列表,如果想一次执行多个任务,可以在列表中添加任务 tasks = [ dict(action=dict(module=module, args=args), register=‘shell_out‘), ] ) play = Play().load(play_source, variable_manager=variable_manager, loader=loader) # actually run it tqm = None try: tqm = TaskQueueManager( inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords, stdout_callback=results_callback, ) result = tqm.run(play) finally: if tqm is not None: tqm.cleanup return json.loads(results_callback.data)
调用例子:
我本地ansible的hosts文件如下:
# more /etc/ansible/hosts [testserver] 192.168.52.128 192.168.52.135
调用如下:
先调用testserver一组主机批量执行date命令:
>>> from exec_ansible import exec_ansible >>> test1 = exec_ansible(module=‘shell‘,args=‘date‘,host=‘testserver‘) { "192.168.52.135": { "warnings": [], "stderr": "", "delta": "0:00:00.003688", "_ansible_no_log": false, "stdout": "Sat Nov 5 18:54:17 CST 2016", "cmd": "date", "_ansible_parsed": true, "rc": 0, "invocation": { "module_args": { "removes": null, "executable": null, "creates": null, "chdir": null, "warn": true, "_raw_params": "date", "_uses_shell": true }, "module_name": "command" }, "start": "2016-11-05 18:54:17.563525", "changed": true, "end": "2016-11-05 18:54:17.567213", "stdout_lines": [ "Sat Nov 5 18:54:17 CST 2016" ] } } { "192.168.52.128": { "warnings": [], "stderr": "", "delta": "0:00:00.003244", "_ansible_no_log": false, "stdout": "Sat Nov 5 21:48:38 CST 2016", "cmd": "date", "_ansible_parsed": true, "rc": 0, "invocation": { "module_args": { "removes": null, "executable": null, "creates": null, "chdir": null, "warn": true, "_raw_params": "date", "_uses_shell": true }, "module_name": "command" }, "start": "2016-11-05 21:48:38.252785", "changed": true, "end": "2016-11-05 21:48:38.256029", "stdout_lines": [ "Sat Nov 5 21:48:38 CST 2016" ] } }
指定单台执行命令:
>>> test2 = exec_ansible(module=‘shell‘,args=‘free -m‘,host=‘192.168.52.128‘) { "192.168.52.128": { "warnings": [], "changed": true, "invocation": { "module_args": { "_raw_params": "free -m", "executable": null, "chdir": null, "creates": null, "removes": null, "_uses_shell": true, "warn": true }, "module_name": "command" }, "rc": 0, "start": "2016-11-05 21:53:10.738545", "_ansible_parsed": true, "delta": "0:00:00.002871", "stdout_lines": [ " total used free shared buffers cached", "Mem: 1869 1786 83 3 312 512", "-/+ buffers/cache: 961 908 ", "Swap: 4047 3 4044 " ], "stderr": "", "end": "2016-11-05 21:53:10.741416", "cmd": "free -m", "_ansible_no_log": false, "stdout": " total used free shared buffers cached\nMem: 1869 1786 83 3 312 512\n-/+ buffers/cache: 961 908 \nSwap: 4047 3 4044 " } }
这里可以从输出中取到输出结果:
>>> stdout = test2["192.168.52.128"]["stdout"] total used free shared buffers cached Mem: 1869 1756 112 2 314 490 -/+ buffers/cache: 951 917 Swap: 4047 4 4043
我写的脚本有个bug,就是当指定一组主机批量执行的时候,返回的函数中,存储内容的只剩下最后执行命令的那台主机的相关信息,做不到把所有的主机的执行信息存储,希望有大神可以解决这个问题,并不吝赐教!!
本文出自 “扮演上帝的小丑” 博客,转载请与作者联系!
原文地址:http://icenycmh.blog.51cto.com/4077647/1870642