下面是從官網的示例程序中拿過來的簡單對接程序,官網連接爲:
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()