当前位置:首页 > 服务端 > ansible 2.4+ allinone 接口

ansible 2.4+ allinone 接口

参考/整理/改写 allinone接口 ,实现playbook,adhoc 调用。

日志部分待完善

#!/usr/bin/env python
# -*- coding=utf-8 -*-

# leaning ansbile api ing~

import json, sys, os
import logging
from ansible import constants
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.inventory.manager import InventoryManager
from ansible.vars.manager import VariableManager
from ansible.inventory.host import Host, Group
from ansible.plugins.callback import CallbackBase
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.executor.playbook_executor import PlaybookExecutor


class MyInventory():

    '''
    resource = [{'hostid': '1231', 'hostname': 'h1', 'hostip': '1.1.1.1'},
                {'hostid': '2345', 'hostname': 'h2', 'hostip': '2.2.2.2'},
                ]
    resource = {'groupname1': {
        'hosts': [
            {'hostid': '1231', 'hostname': 'h1', 'hostip': '1.1.1.1'},
            {'hostid': '2231', 'hostname': 'h2', 'hostip': '1.1.1.2'},
                 ],
        'groupvars': {"k1":"v1"}
                              },
                'groupname2': {'hosts': [], 'groupvars': {}},
                              }
    '''

    # edit ori code  ansible/inventory/manage.pay line215  try if C.InventoryManager_PARSE_NOSOURCE:pass
    constants.InventoryManager_PARSE_NOSOURCE=True
    def __init__(self,resource):
        self.resource=resource
        self.loader=DataLoader()
        # self.inventory=InventoryManager(loader=self.loader,sources=['/etc/ansible/hosts'])
        self.inventory=InventoryManager(loader=self.loader)
        self.variable_manager=VariableManager(loader=self.loader,inventory=self.inventory)
        self._parse(self.resource)

    def _parse(self,resource):
        if isinstance(resource,list):
            self._addGroupHosts(self.resource)
        elif isinstance(resource,dict):
            # logging.info('parsing resuorce: %s'%(self.resource))
            for groupname,hosts_and_groupvars in self.resource.items():
                print("[1] groupname: %s |hostsandvars: %s"%(groupname,hosts_and_groupvars))                                                    # debug [1]
                self._addGroupHosts(hosts_and_groupvars.get('hosts'),groupname,hosts_and_groupvars.get('groupvars'))

        else:
            logging.error('resource error ,need dict or list')

    def _addGroupHosts(self,hosts,groupname='default',groupvars=None):
        self.inventory.add_group(group=groupname)
        group=Group(groupname)
        if groupvars:
            for k,v in groupvars.items():
                group.set_variable(k,v)

        # hosts=[{'hostid':'123','hostname':'h1','hostip':'192.168.188.20'}
        for host in hosts:
            hostid=host.get('hostid')
            hostname=host.get('hostname')
            hostip=host.get('hostip')
            username=host.get('username')
            password=host.get('password')
            port=host.get('port',22)
            sshkey=host.get('sshkey')
            if hostname:
                self.inventory.add_host(host=hostname,group=groupname)   # by default, indentify by hostname and need
                hostobj= self.inventory.get_host(hostname=hostname)     # add host= , get hostname=

                self.variable_manager.set_host_variable(host=hostobj,varname='ansible_ssh_host',value=hostip)
                self.variable_manager.set_host_variable(host=hostobj,varname='ansible_ssh_port',value=port)
                self.variable_manager.set_host_variable(host=hostobj,varname='ansible_ssh_user',value=username)
                self.variable_manager.set_host_variable(host=hostobj,varname='ansible_ssh_pass',value=password)
                self.variable_manager.set_host_variable(host=hostobj,varname='ansible_ssh_private_key_file',value=sshkey)

                # TODO: other vars such as become-method-user-pass
                #hostobj.set_variable('ansible_ssh_port',port)
                for k,v in host.items():
                    if k not in ['hostip','port','username','password','sshkey']:
                        hostobj.set_variable(k,v)
            else:
                logging.warning('resource error:cant get hostname from | %s'%resource)

    def testcase(self):
        print(self.inventory.get_groups_dict())
        host=self.inventory.get_host(hostname='h1')
        print(self.variable_manager.get_vars(host=host))


class ADhocCallback(CallbackBase):
    def __init__(self, *args, **kwargs):
        super(ADhocCallback, self).__init__(*args, **kwargs)
        self.result_row={'ok':{},'failed':{},'unreachable':{}}

    def v2_runner_on_ok(self, result,  *args, **kwargs):
        self.result_row['ok'][result._host.get_name()] = result._result
        logging.info('===v2_runner_on_ok===host=%s===result=%s' % (result._host.get_name(), result._result))


    def v2_runner_on_unreachable(self, result,*args,**kwargs):
        self.result_row['unreachable'][result._host.get_name()]=result._result

    def v2_runner_on_failed(self, result,  *args, **kwargs):
        self.result_row['failed'][result._host.get_name()]=result._result


class PlayBookCallback(CallbackBase):
    # CALLBACK_VERSION = 2.0
    def __init__(self, *args, **kwargs):
        super(PlayBookCallback, self).__init__(*args, **kwargs)
        self.result_row={'ok':{},'failed':{},'unreachable':{},'skipped':{},'status':{}}

    def v2_runner_on_ok(self, result,  *args, **kwargs):
        # print(result._host.get_name())
        # print("run on ok %s"%result._result)
        self.result_row['ok'][result._host.get_name()] = result._result

    def v2_runner_on_unreachable(self, result,*args,**kwargs):
        self.result_row['unreachable'][result._host.get_name()]=result._result

    def v2_runner_on_failed(self, result,  *args, **kwargs):
        self.result_row['failed'][result._host.get_name()]=result._result

    def v2_runner_on_skipped(self, result):
        self.result_row['skipped'][result._host.get_name()]=result._result

    def v2_playbook_on_stats(self, stats):
        # print(stats)
        hosts = sorted(stats.processed.keys())
        for h in hosts:
            t = stats.summarize(h)
            self.result_row['status'][h] = {
                                       "ok":t['ok'],
                                       "changed" : t['changed'],
                                       "unreachable":t['unreachable'],
                                       "skipped":t['skipped'],
                                       "failed":t['failures']
                                   }




class Runner():
    def __init__(self,resource=None):
        self.resource = resource
        self.inventory = None
        self.variable_manager = None
        self.loader = None
        self.options = None
        self.passwords = None
        self.callback = None
        self.__initializeData()
        self.results_raw = None

    def __initializeData(self):
        Options = namedtuple('Options', ['connection','module_path', 'forks', 'timeout',  'remote_user',
                'ask_pass', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args',
                'scp_extra_args', 'become', 'become_method', 'become_user', 'ask_value_pass', 'verbosity',
                'check', 'listhosts', 'listtasks', 'listtags', 'syntax','diff'])
        self.options = Options(connection='smart', module_path=None, forks=100, timeout=10,
                remote_user='root', ask_pass=False, private_key_file=None, ssh_common_args=None, ssh_extra_args=None,
                sftp_extra_args=None, scp_extra_args=None, become=None, become_method=None,
                become_user='root', ask_value_pass=False, verbosity=None, check=False, listhosts=False,
                listtasks=False, listtags=False, syntax=False, diff=True)
        self.passwords = dict(sshpass=None, becomepass=None)
        self.loader = DataLoader()

        # case1: no resource , use /etc/ansible/hosts
        if self.resource:
            myinventory = MyInventory(self.resource)
            self.inventory=myinventory.inventory
            self.variable_manager=myinventory.variable_manager

    def run_model(self, host_list, module_name, module_args):
        """
        ansible group1 -m shell -a 'ls /tmp'
        """
        self.callback = ADhocCallback()
        play_source = dict(
                name="Ansible Play",
                hosts=host_list,
                gather_facts='no',
                tasks=[dict(action=dict(module=module_name, args=module_args))]
        )
        play = Play().load(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 = "minimal",
            )
            tqm._stdout_callback = self.callback
            constants.HOST_KEY_CHECKING = False #关闭第一次使用ansible连接客户端是输入命令
            tqm.run(play)
            self.results_raw=self.callback.result_row
        except Exception as err:
            print(err)
        finally:
            if tqm is not None:
                tqm.cleanup()

    def run_playbook(self,playbookpath,extra_vars=None,localhostlist=None):
        # TODO log now is mixing in hostsresult . => play n/group /task n /

        # case1: no resource , use /etc/ansible/hosts
        if localhostlist:
            self.inventory=InventoryManager(loader=self.loader,sources=localhostlist)
            self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)

        self.callback=PlayBookCallback()
        try:
            # if self.redisKey:self.callback = PlayBookResultsCollectorToSave(self.redisKey,self.logId)
            if extra_vars:self.variable_manager.extra_vars = extra_vars
            executor = PlaybookExecutor(
                playbooks=[playbookpath],
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=self.options,
                passwords=self.passwords,
            )
            executor._tqm._stdout_callback = self.callback
            constants.HOST_KEY_CHECKING = False #关闭第一次使用ansible连接客户端是输入命令
            executor.run()
            self.results_raw=self.callback.result_row
        except Exception as err:
            return False


def _example1():
    # test inventory
    resource={'group1':{'hosts':[{'hostid':'123','hostname':'h1','hostip':'192.168.188.200','username':'root',
                                  'password':'admin','port':'22','sshkey':'','k1':'v1'},
                                 {'hostid': '223', 'hostname': 'h2', 'hostip': '192.168.188.201', 'username': 'root',
                                  'password': '1qaz@WSX', 'port': '22', 'sshkey': '',},
                                 ],
                        'groupvars':{"g1key":"g1value"}},
              }
    # test inventory
    iobj=MyInventory(resource)
    iobj.testcase()


def _example2():
    # server playbook +  server inventory
    runner = Runner()
    runner.run_playbook(playbookpath='/etc/ansible/myplay.yaml', localhostlist=['/etc/ansible/hosts'])
    result = runner.results_raw
    print(json.dumps(result, indent=4))


def _example3():
    # server playbook  + dynamic inventory
    resource={'group1':{'hosts':[{'hostid':'123','hostname':'h1','hostip':'192.168.188.200','username':'root',
                                  'password':'admin','port':'22','sshkey':'','k1':'v1'},
                                 {'hostid': '223', 'hostname': 'h2', 'hostip': '192.168.188.201', 'username': 'root',
                                  'password': '1qaz@WSX', 'port': '22', 'sshkey': '',},
                                 ],
                        'groupvars':{"g1key":"g1value"}},
              }
    runner = Runner(resource)
    runner.run_playbook(playbookpath='/etc/ansible/myplay.yaml')



def _example4():
    #  use adhoc  + dynamic inventory
    resource={'group1':{'hosts':[{'hostid':'123','hostname':'h1','hostip':'192.168.188.200','username':'root',
                                  'password':'admin','port':'22','sshkey':'','k1':'v1'},
                                 {'hostid': '223', 'hostname': 'h2', 'hostip': '192.168.188.201', 'username': 'root',
                                  'password': '1qaz@WSX', 'port': '22', 'sshkey': '',},
                                 ],
                        'groupvars':{"g1key":"g1value"}},
              }
    runner = Runner(resource)
    runner.run_model(host_list=['h2'], module_name='shell', module_args='ls /tmp')
    result = runner.results_raw
    print(result)


if __name__ == '__main__':


    # _example1()
    # _example2()
    # _example3()
    _example4()

 

作者:EngineTang
来源链接:https://www.cnblogs.com/infaaf/p/9534332.html

版权声明:
1、Java侠(https://www.javaxia.com)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaxia.com/server/124953.html

分享给朋友:

“ansible 2.4+ allinone 接口” 的相关文章