• Flask Ansible自动化平台搭建(持续更新)


    一:简介

    使用Ansible + Flask + Celery搭建web平台。
    

    目录结构
    .
    ├── ansible_api
    │   ├── ansible_playbook_inventory.py
    │   ├── ansible_playbook.py
    │   ├── ansible_task.py
    │   ├── init.py
    │   └── README.md
    ├── app.py
    ├── config
    │   ├── Config.ini
    │   └── hosts
    ├── database
    │   ├── controller.py
    │   ├── db_controller.py
    │   └── init.py
    ├── README.md
    ├── requirements.txt
    └── templates
    └── index.html

    4 directories, 14 files

    二:Ansible Api代码

    Ansible Task Api 这一部分跟命令行执行Ansible命令格式一样
    ansible_task.py

    #!/usr/bin/env python
    # coding:utf-8
    
    import json
    from collections import namedtuple
    from ansible.parsing.dataloader import DataLoader
    from ansible.vars import VariableManager
    from ansible.inventory import Inventory
    from ansible.playbook.play import Play
    from ansible.executor.task_queue_manager import TaskQueueManager
    from ansible.plugins.callback import CallbackBase
    
    # 这里为封装的返回信息,让我们获取返回信息更加方便进行处理
    class ResultCallback(CallbackBase):
        def __init__(self, *args):
            super(ResultCallback, self).__init__(display=None)
            self.status_ok = json.dumps({}, ensure_ascii=False)
            self.status_fail = json.dumps({}, ensure_ascii=False)
            self.status_unreachable = json.dumps({}, ensure_ascii=False)
            self.status_playbook = ''
            self.status_no_hosts = False
            self.host_ok = {}
            self.host_failed = {}
            self.host_unreachable = {}
    
        def v2_runner_on_ok(self, result):
            host = result._host.get_name()
            self.runner_on_ok(host, result._result)
            self.host_ok[host] = result
    
        def v2_runner_on_failed(self, result, ignore_errors=False):
            host = result._host.get_name()
            self.runner_on_failed(host, result._result, ignore_errors)
            self.host_failed[host] = result
    
        def v2_runner_on_unreachable(self, result):
            host = result._host.get_name()
            self.runner_on_unreachable(host, result._result)
            self.host_unreachable[host] = result
    
    class Task():
       def __init__(self, module, command):
    	self.module = module
            self.command = command
       def run(self):
            # 这里跟ansible.cfg文件中的配置一样
     	Options = namedtuple('Options', 
    	       ['listtags', 
    		'listtasks', 
    		'listhosts', 
    		'syntax', 
    		'connection',
    		'module_path',
    		'forks', 
    		'remote_user', 
    		'private_key_file', 
    		'ssh_common_args', 
    		'ssh_extra_args',
    		'sftp_extra_args', 
    		'scp_extra_args', 
    		'become', 
    		'become_method', 
    		'become_user',
    		'verbosity', 
    		'check']
    		)
    	variable_manager = VariableManager()
    	loader = DataLoader()
    	options = Options(listtags=False, 
    		listtasks=False, 
    		listhosts=False, 
    		syntax=False, 
    		connection='smart',
    		module_path='/usr/lib/python2.6/site-packages/ansible/modules/', 
    		forks=100,
    		remote_user='root', 
    		private_key_file=None, 
    		ssh_common_args=None, 
    		ssh_extra_args=None,
    		sftp_extra_args=None, 
    		scp_extra_args=None, 
    		become=False, 
    		become_method=None, 
    		become_user='root',
    		verbosity=None, 
    		check=False
    		)
    	passwords = dict(vault_pass='secret')
            # 传入的hosts文件
    	inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list='config/hosts')
    	variable_manager.set_inventory(inventory)
             
            # 要执行的task
    	play_source =  dict(
                name = "Ansible Play",
                hosts = 'all',
                gather_facts = 'no',
                tasks = [
                    dict(action=dict(module=self.module, args=self.command), register='shell_out'),
                    #dict(action=dict(module='shell', args='id'), register='shell_out'),
                    #dict(action=dict(module='shell', args=dict(msg='{{shell_out.stdout}}')))
                ]
            )
    	play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
    
    	tqm = None
    	try:
        	    tqm = TaskQueueManager(
                  inventory=inventory,
                  variable_manager=variable_manager,
                  loader=loader,
                  options=options,
                  passwords=passwords,
              )
    	    self.results_callback = ResultCallback()
                tqm._stdout_callback = self.results_callback
        	    result = tqm.run(play)
    	finally:
        	    if tqm is not None:
                    tqm.cleanup()
    
       def get_result(self):
    	# 执行任务
    	self.run()
            result_all = {'success': {}, 'failed': {}, 'unreachable': {}}
            for host, result in self.results_callback.host_ok.items():
    	    info = {}
    	    info['stdout'] = result._result['stdout']
    	    info['delta'] = result._result['delta']
                result_all['success'][host] = info
    
            for host, result in self.results_callback.host_failed.items():
                if 'msg' in result._result:
                    result_all['failed'][host] = result._result['msg']
    
            for host, result in self.results_callback.host_unreachable.items():
                if 'msg' in result._result:
                    result_all['unreachable'][host] = result._result['msg']
    
            return json.dumps(result_all, ensure_ascii=False,sort_keys=True, indent=2)
    
    if __name__ =='__main__':
        res=Task('shell', 'hostname')
        print res.get_result()
    

    Ansible playbook,执行playbook文件
    ansible_playbook.py

    #!/usr/bin/python
    #coding:utf8
    
    import os
    import json
    from collections import namedtuple
    from ansible.inventory import Inventory
    from ansible.vars import VariableManager
    from ansible.parsing.dataloader import DataLoader
    from ansible.executor.playbook_executor import PlaybookExecutor
    from ansible.plugins.callback import CallbackBase
    from ansible.errors import AnsibleParserError
    
    
    class mycallback(CallbackBase):
    
        def __init__(self, *args):
            super(mycallback, self).__init__(display=None)
            self.status_ok = json.dumps({}, ensure_ascii=False)
            self.status_fail = json.dumps({}, ensure_ascii=False)
            self.status_unreachable = json.dumps({}, ensure_ascii=False)
            self.status_playbook = ''
            self.status_no_hosts = False
            self.host_ok = {}
            self.host_failed = {}
            self.host_unreachable = {}
    
        def v2_runner_on_ok(self, result):
            host = result._host.get_name()
            self.runner_on_ok(host, result._result)
            self.host_ok[host] = result
    
        def v2_runner_on_failed(self, result, ignore_errors=False):
            host = result._host.get_name()
            self.runner_on_failed(host, result._result, ignore_errors)
            self.host_failed[host] = result
    
        def v2_runner_on_unreachable(self, result):
            host = result._host.get_name()
            self.runner_on_unreachable(host, result._result)
            self.host_unreachable[host] = result
    
        def v2_playbook_on_no_hosts_matched(self):
            self.playbook_on_no_hosts_matched()
            self.status_no_hosts = True
    
        def v2_playbook_on_play_start(self, play):
            self.playbook_on_play_start(play.name)
            self.playbook_path = play.name
    
    
    class ansible_playbook():
    
        # 初始化各项参数,根据需求修改
        def __init__(self, playbook,
                     host_list='/etc/ansible/hosts',
                     ansible_cfg=None,
                     passwords={}):
            self.playbook_path = playbook
            self.passwords = passwords
            Options = namedtuple('Options', ['listtags', 'listtasks', 'listhosts', 'syntax', 'connection','module_path','forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args','sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user','verbosity', 'check'])
    	self.options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='smart',module_path='/usr/lib/python2.6/site-packages/ansible/modules/', forks=100,remote_user='root', private_key_file=None, ssh_common_args=None, ssh_extra_args=None,sftp_extra_args=None, scp_extra_args=None, become=False, become_method=None, become_user='root',verbosity=None, check=False)
            if ansible_cfg != None:
                os.environ["ANSIBLE_CONFIG"] = ansible_cfg
            self.variable_manager = VariableManager()
            self.loader = DataLoader()
            self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=host_list)
    
        # 定义运行的方法和返回值
        def run(self):
            #判断playbook是否存在
            if not os.path.exists(self.playbook_path):
                code = 1000
                results = {'playbook': self.playbook_path, 'msg': self.playbook_path + ' playbook is not exist',
                           'flag': False}
            pbex = PlaybookExecutor(playbooks=[self.playbook_path],
                                    inventory=self.inventory,
                                    variable_manager=self.variable_manager,
                                    loader=self.loader,
                                    options=self.options,
                                    passwords=self.passwords)
            self.results_callback = mycallback()
            pbex._tqm._stdout_callback = self.results_callback
    
            try:
                code = pbex.run()
            except AnsibleParserError:
                code = 1001
                results = {'playbook': self.playbook_path, 'msg': self.playbook_path + ' playbook have syntax error',
                           'flag': False}
                return code, results
            if self.results_callback.status_no_hosts:
                code = 1002
                results = {'playbook': self.playbook_path, 'msg': self.results_callback.status_no_hosts, 'flag': False,
                           'executed': False}
                return code, results
    
        def get_result(self):
            result_all = {'success': {}, 'failed': {}, 'unreachable': {}}
    
            for host, result in self.results_callback.host_ok.items():
                result_all['success'][host] = result._result
    
            for host, result in self.results_callback.host_failed.items():
    	    if 'msg' in result._result:
                    result_all['failed'][host] = result._result['msg']
    
            for host, result in self.results_callback.host_unreachable.items():
    	    if 'msg' in result._result:
                    result_all['unreachable'][host] = result._result['msg']
    	
    	return json.dumps(result_all, ensure_ascii=False,sort_keys=True, indent=2)
    
    if __name__ == '__main__':
        play_book = ansible_playbook(playbook='/etc/ansible/site.yml')
        play_book.run()
        print play_book.get_result()
    

    Ansible playbook支持动态inventory传入
    ansible_playbook_inventory.py

    #!/usr/bin/python
    #coding:utf8
    
    import os
    import json
    from collections import namedtuple
    from ansible.inventory import Inventory
    from ansible.vars import VariableManager
    from ansible.parsing.dataloader import DataLoader
    from ansible.executor.playbook_executor import PlaybookExecutor
    from ansible.plugins.callback import CallbackBase
    from ansible.errors import AnsibleParserError
    from ansible.inventory.group import Group
    from ansible.inventory.host import Host
    
    class mycallback(CallbackBase):
        def __init__(self, *args):
            super(mycallback, self).__init__(display=None)
            self.status_ok = json.dumps({}, ensure_ascii=False)
            self.status_fail = json.dumps({}, ensure_ascii=False)
            self.status_unreachable = json.dumps({}, ensure_ascii=False)
            self.status_playbook = ''
            self.status_no_hosts = False
            self.host_ok = {}
            self.host_failed = {}
            self.host_unreachable = {}
    
        def v2_runner_on_ok(self, result):
            host = result._host.get_name()
            self.runner_on_ok(host, result._result)
            self.host_ok[host] = result
    
        def v2_runner_on_failed(self, result, ignore_errors=False):
            host = result._host.get_name()
            self.runner_on_failed(host, result._result, ignore_errors)
            self.host_failed[host] = result
    
        def v2_runner_on_unreachable(self, result):
            host = result._host.get_name()
            self.runner_on_unreachable(host, result._result)
            self.host_unreachable[host] = result
    
        def v2_playbook_on_no_hosts_matched(self):
            self.playbook_on_no_hosts_matched()
            self.status_no_hosts = True
    
        def v2_playbook_on_play_start(self, play):
            self.playbook_on_play_start(play.name)
            self.playbook_path = play.name
    
    class MyInventory(Inventory):  
        """ 
        this is my ansible inventory object. 
        """  
        def __init__(self, resource, loader, variable_manager):  
            """ 
            resource的数据格式是一个列表字典,比如 
                { 
                    "group1": { 
                        "hosts": [{"hostname": "10.0.0.0", "port": "22", "username": "test", "password": "pass"}, ...], 
                        "vars": {"var1": value1, "var2": value2, ...} 
                    } 
                } 
     
            如果你只传入1个列表,这默认该列表内的所有主机属于my_group组,比如 
                [{"hostname": "10.0.0.0", "port": "22", "username": "test", "password": "pass"}, ...] 
            """  
            self.resource = resource  
            self.inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=[])  
            self.gen_inventory()  
      
        def my_add_group(self, hosts, groupname, groupvars=None):  
            """ 
            add hosts to a group 
            """  
            my_group = Group(name=groupname)  
      
            # if group variables exists, add them to group  
            if groupvars:  
                for key, value in groupvars.iteritems():  
                    my_group.set_variable(key, value)  
      
            # add hosts to group  
            for host in hosts:  
                # set connection variables  
                hostname = host.get("hostname")  
                hostip = host.get('ip', hostname)  
                hostport = host.get("port")  
                username = host.get("username")  
                password = host.get("password")  
                ssh_key = host.get("ssh_key")  
                my_host = Host(name=hostname, port=hostport)  
                my_host.set_variable('ansible_ssh_host', hostip)  
                my_host.set_variable('ansible_ssh_port', hostport)  
                my_host.set_variable('ansible_ssh_user', username)  
                my_host.set_variable('ansible_ssh_pass', password)  
                my_host.set_variable('ansible_ssh_private_key_file', ssh_key)  
      
                # set other variables  
                for key, value in host.iteritems():  
                    if key not in ["hostname", "port", "username", "password"]:  
                        my_host.set_variable(key, value)  
                # add to group  
                my_group.add_host(my_host)  
      
            self.inventory.add_group(my_group)  
      
        def gen_inventory(self):  
            """ 
            add hosts to inventory. 
            """  
            if isinstance(self.resource, list):  
                self.my_add_group(self.resource, 'default_group')  
            elif isinstance(self.resource, dict):  
                for groupname, hosts_and_vars in self.resource.iteritems():  
                    self.my_add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))
    
    class ansible_playbook(object):
        # 初始化各项参数,根据需求修改
        def __init__(self, playbook, hosts,ansible_cfg=None, passwords={}):
            self.playbook_path = playbook
    	self.hosts = hosts
            self.passwords = passwords
            Options = namedtuple('Options', 
    			    ['listtags', 
    		            'listtasks', 
                                'listhosts', 
                                'syntax', 
                                'connection',
                                'module_path',
                                'forks', 
                                'remote_user', 
                                'private_key_file', 
                                'ssh_common_args', 
                                'ssh_extra_args',
                                'sftp_extra_args', 
                                'scp_extra_args', 
                                'become', 
                                'become_method', 
                                'become_user',
                                'verbosity', 
                                'check'
                                ])
    	self.options = Options(listtags=False, 
                                   listtasks=False, 
                                   listhosts=False, 
                                   syntax=False, 
                                   connection='smart',
                                   module_path='/usr/lib/python2.6/site-packages/ansible/modules/', 
                                   forks=100,remote_user='root', 
                                   private_key_file=None, 
                                   ssh_common_args=None, 
                                   ssh_extra_args=None,
                                   sftp_extra_args=None, 
                                   scp_extra_args=None, 
                                   become=False, 
                                   become_method=None, 
                                   become_user='root',
                                   verbosity=None, 
                                   check=False
                                  )
            if ansible_cfg != None:
                os.environ["ANSIBLE_CONFIG"] = ansible_cfg
            self.variable_manager = VariableManager()
            self.loader = DataLoader()
            #self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=host_list)
            self.inventory = MyInventory(self.hosts, self.loader, self.variable_manager).inventory 
      	self.variable_manager.set_inventory(self.inventory)	
    
        # 定义运行的方法和返回值
        def run(self):
            #判断playbook是否存在
            if not os.path.exists(self.playbook_path):
                code = 1000
                results = {'playbook': self.playbook_path, 
    		       'msg': self.playbook_path + ' playbook is not exist',
                           'flag': False
    		      }
            pbex = PlaybookExecutor(playbooks=[self.playbook_path],
                                    inventory=self.inventory,
                                    variable_manager=self.variable_manager,
                                    loader=self.loader,
                                    options=self.options,
                                    passwords=self.passwords
    				)
            self.results_callback = mycallback()
            pbex._tqm._stdout_callback = self.results_callback
    
            try:
                code = pbex.run()
            except AnsibleParserError:
                code = 1001
                results = {'playbook': self.playbook_path, 'msg': self.playbook_path + ' playbook have syntax error',
                           'flag': False}
                return code, results
            if self.results_callback.status_no_hosts:
                code = 1002
                results = {'playbook': self.playbook_path, 'msg': self.results_callback.status_no_hosts, 'flag': False,
                           'executed': False}
                return code, results
    
        def get_result(self):
            result_all = {'success': {}, 'failed': {}, 'unreachable': {}}
    
            for host, result in self.results_callback.host_ok.items():
                result_all['success'][host] = result._result
    
            for host, result in self.results_callback.host_failed.items():
    	    if 'msg' in result._result:
                    result_all['failed'][host] = result._result['msg']
    
            for host, result in self.results_callback.host_unreachable.items():
    	    if 'msg' in result._result:
                    result_all['unreachable'][host] = result._result['msg']
    	
    	return json.dumps(result_all, ensure_ascii=False,sort_keys=True, indent=2)
    
    if __name__ == '__main__':
        # 动态资产信息传入 
        hosts = {
                 "group1": {
                        "hosts": [{"hostname": "192.168.30.141", "port": "22", "username": "root", "password": "oracle"}],
                        "vars": {"var1": "value1"}
                 }
        }
    
        play_book = ansible_playbook(playbook='/etc/ansible/playbook_yaml/user.yml', hosts = hosts)
        play_book.run()
        print play_book.get_result()
    

    目前位置Ansible API三个文件准备好了,下一步开始准备数据库的信息录入。

  • 相关阅读:
    896. 单调数列
    819. 最常见的单词
    collections.Counter()
    257. 二叉树的所有路径
    万里长征,始于足下——菜鸟程序员的学习总结(三)
    Ogre启动过程&原理
    Ogre导入模型
    四元数
    Ogre3D嵌入Qt框架
    如何搭建本地SVN服务
  • 原文地址:https://www.cnblogs.com/GXLo/p/8507470.html
Copyright © 2020-2023  润新知