python Ansible API使用

Ansible版本2.6.4,記錄下ansible API使用,合入到運(yùn)營(yíng)系統(tǒng),會(huì)使用到ansible批量操作服務(wù)器,ansible本身就是python寫(xiě)的,所以對(duì)于python來(lái)說(shuō)可以直接調(diào)用,有興趣了解更多可以去官網(wǎng)看看https://docs.ansible.com/ansible/latest/index.html

# coding:utf-8
#!/usr/bin/env python

import json
import shutil
from collections import namedtuple
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.errors import AnsibleError
import ansible.constants as C

class ResultCallback(CallbackBase):
    """結(jié)果回調(diào)"""
    def __init__(self, *args, **kwargs):
        super(ResultCallback, self).__init__(*args, **kwargs)
        self.host_ok = {}
        self.host_unreachable = {}
        self.host_failed = {}
        self.ret = {
            'host_ok': '',
            'host_unreachable': '',
            'host_failed': ''
        }

    def v2_runner_on_unreachable(self, result):
        self.host_unreachable[result._host.get_name()] = result
        self.ret['host_unreachable'] = {result._host.name: result._result}

    def v2_runner_on_ok(self, result, *args, **kwargs):
        self.host_ok[result._host.get_name()] = result
        self.ret['host_ok'] = {result._host.name: result._result}

    def v2_runner_on_failed(self, result, *args, **kwargs):
        self.host_failed[result._host.get_name()] = result
        self.ret['host_failed'] = {result._host.name: result._result}



class AnsibleApi():
    def __init__(self, sources='conf/ansible/hosts', name="ansible Play",hosts=None,actions=None):
        '''
        創(chuàng)建參數(shù),為保證每個(gè)參數(shù)都被設(shè)置,ansible使用可命名元組
        '''
        self.Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'diff'])
        self.options = self.Options(connection='ssh', module_path=['/to/mymodules'], forks=30, become=None, become_method=None, become_user=None, check=False, diff=False)

        '''初始化loader類(lèi)'''
        self.loader = DataLoader()  # 用于讀取與解析yaml和json文件
        self.passwords = dict(vault_pass='secret')

        '''初始化結(jié)果回調(diào)方法,用于接收返回的結(jié)果'''
        self.results_callback = ResultCallback()

        '''指定inventory,即我們的ansible hosts文件,使用路徑指定一個(gè)host文件,或者一個(gè)逗號(hào)分割host的字符串'''
        self.inventory = InventoryManager(loader=self.loader, sources=sources)

        '''合并所有不同的資源成一個(gè)統(tǒng)一的變量管理視圖,這些由變量管理器完成'''
        self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)
        '''play_source 創(chuàng)建我們?nèi)蝿?wù)的數(shù)據(jù)結(jié)構(gòu),tasks里面就是我們定義的yaml文件所做的步驟'''

        if actions == None:
            print "no actions"
            raise AnsibleError
        if hosts == None:
            print  "no hosts"
            raise AnsibleError
        self.play_source = dict(
            name=name,
            hosts=hosts,
            gather_facts='no',
            tasks=actions,
                #dict(action=dict(module='shell', args='ls'), register='shell_out'),
                #dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}')))
        )

    def _run_task(self):
        '''run task'''
        play = Play().load(self.play_source, variable_manager=self.variable_manager, loader=self.loader)
        tqm = None
        try:
            tqm = TaskQueueManager(
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=self.options,
                passwords=self.passwords,
                stdout_callback=self.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 structres we use to communicate with them
            if tqm is not None:
                tqm.cleanup()

            # Remove ansible tmpdir
            shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)


if __name__ == '__main__':
    '''
    使用舉例, ip:,號(hào)分割
    '''
    ip = 'localhost,'
    test_key = "key1\n \
                key2"

    actions = [
        dict(action=dict(module='shell', args='ls', register='shell_out')),
        dict(action=dict(module='authorized_key', args='user=brick key="%s"' % test_key))
    ]
    ansible_actions = AnsibleApi(sources='../conf/ansible/hosts', name="ansible test", hosts=ip, actions=actions)
    ansible_actions._run_task()

來(lái)自官網(wǎng)的python api example,簡(jiǎn)單的封裝了一下,就可以用了!其中每一步做了什么我都做了注釋?zhuān)绻€需要了解更詳細(xì)的內(nèi)容,推薦讀下官方文檔,甚至可以讀下源碼,以后有空了再研究下源碼,現(xiàn)在業(yè)務(wù)忙也沒(méi)時(shí)間搞

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容