下面是从官网的示例程序中拿过来的简单对接程序,官网连接为:
https://docs.ansible.com/ansible/latest/dev_guide/developing_api.html
#!/usr/bin/python
#encoding:utf-8
import json
import shutil
from ansible.module_utils.common.collections import ImmutableDict
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.plugins.callback import CallbackBase
from ansible import context
import ansible.constants as C
class ResultCallback(CallbackBase):
"""
回调函数,如果执行成功会调用`v2_runner_on_ok`函数
如果执行失败会调用 `v2_runner_on_failed`函数
如果执行的任务主机不可达会调用 `v2_runner_on_unreachable`函数
"""
def v2_runner_on_ok(self, result, **kwargs):
"""
如果task执行成功会调用这个函数,进行汇总
"""
# 查看task的相关字段,
# print(result._task_fields)
# 返回结果的主机IP
host = result._host
# 打印每台主机返回的结果
print(json.dumps({host.name: result._result}, indent=4))
# 执行失败触发此回调函数
def v2_runner_on_failed(self, result, ignore_errors=False):
# self.print_help_message()
print('FAILED! => task: %s; message: %s', result._task, self._dump_results(result._result))
# 主机不可达触发此回调函数
def v2_runner_on_unreachable(self, result):
# self.print_help_message()
print('UNREACHABLE! => message: %s', result._task, self._dump_results(result._result))
def ExecutionTask():
# since the API is constructed for CLI it expects certain options to always be set in the context object
# 注意这里connection如果是local,执行shell命令也只会本地执行。
context.CLIARGS = ImmutableDict(connection='ssh', module_path=['/to/mymodules'], forks=10, become='yes',
become_method='sudo', become_user='root', check=False, diff=False)
# initialize needed objects
loader = DataLoader() # Takes care of finding and reading yaml, json and ini files
passwords = dict(vault_pass='secret')
# Instantiate our ResultCallback for handling results as they come in. Ansible expects this to be one of its main display outlets
results_callback = ResultCallback()
# create inventory, use path to host config file as source or hosts in a comma separated string
# 清单列表,这里是读取本地的hosts.ini文件作为清单列表
inventory = InventoryManager(loader=loader, sources='hosts.ini')
# variable manager takes care of merging all the different sources to give you a unified view of variables available in each context
variable_manager = VariableManager(loader=loader, inventory=inventory)
# create data structure that represents our play, including tasks, this is basically what our YAML loader does internally.
play_source = dict(
name = "Ansible Play",
hosts = 'servers',
gather_facts = 'no',
tasks = [
# get net card serial number
dict(action=dict(module='shell', cmd= r'ls' ), register='shellOut'),
# setup模块
dict(action=dict(module='setup' ), register='SetupOut')
]
)
# Create play object, playbook objects use .load instead of init or new methods,
# this will also automatically create the task objects from the info provided in play_source
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
# Run it - instantiate task queue manager, which takes care of forking and setting up all objects to iterate over host list and tasks
tqm = None
try:
tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
passwords=passwords,
stdout_callback=results_callback, # Use our custom callback instead of the ``default`` callback plugin, which prints to stdout
)
result = tqm.run(play) # most interesting data for a play is actually sent to the callback's methods
finally:
# we always need to cleanup child procs and the structures we use to communicate with them
if tqm is not None:
tqm.cleanup()
# Remove ansible tmpdir
shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
def main():
# 执行task的函数
ExecutionTask()
if __name__=="__main__":
main()