zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    继承与多态
    String作业
    课后作业及动手动脑
    作业3
    动手动脑
    实验任务四
    动手动脑
    课堂练习01
    《大道至简》第一章读后感伪代码
    C++常用编程关键字
  • 原文地址:https://www.cnblogs.com/infaaf/p/9534332.html
Copyright © 2011-2022 走看看