python對接ansible api簡單程序

下面是從官網的示例程序中拿過來的簡單對接程序,官網連接爲:

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()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章