예제 #1
0
    def __init__(self, mongoclient=None, redisclient=None):
        
        '''
        这是用户管理部分的MVC中的C
        '''
        
        self.logger = logging.getLogger("devops")
        self.userinfo_mongocollect = 'user.login.info'
        self.userinfo_rediskey = 'devops:userinfo'
        self.privacy_mongocollect = 'user.privacy'
        if mongoclient is None :
            self.mongoclient = Op_Mongo()
            self.logger.warn('无法继承,需要初始化mongodb连接')
        else :
            self.mongoclient = mongoclient
            
        if redisclient is None :
            self.redisclient = Op_Redis()
            self.logger.warn('无法继承,需要初始化redis连接')
        else :
            self.redisclient = redisclient

        self.password_api = Manager_Password()
        self.expiretime = 60 * 60 * 24
        self.rediskey_prefix = 'devops:'
예제 #2
0
    def __init__(self):
        '''
        该class用于写日志到mongodb服务器中
        __init__()用于初始化mongo
        '''

        from library.connecter.database.mongo import Op_Mongo
        self.mongoclient = Op_Mongo(dest='log')
        self.default_log_dict = log_category_dict['default']
예제 #3
0
    def __init__(self, mongoclient=None, redisclient=None):
        self.logger = logging.getLogger("weboper")
        if mongoclient is None:
            self.mongoclient = Op_Mongo()
            self.logger.warn('无法继承,需要初始化mongodb连接')
        else:
            self.mongoclient = mongoclient

        if redisclient is None:
            self.redisclient = Op_Redis()
            self.logger.warn('无法继承,需要初始化redis连接')
        else:
            self.redisclient = redisclient

        self.usermanager_api = Manager_User(mongoclient=self.mongoclient,
                                            redisclient=self.redisclient)
        self.privacy_api = Manager_Privacy(mongoclient=self.mongoclient,
                                           redisclient=self.redisclient)
        self.ansible_report_api = Manager_Report(mongoclient=self.mongoclient,
                                                 redisclient=self.redisclient)
        self.ansible_option_api = Manager_Option(mongoclient=self.mongoclient,
                                                 redisclient=self.redisclient)

        self.uri_api = Manager_Uri(mongoclient=self.mongoclient,
                                   redisclient=self.redisclient)
        self.inventory_api = Manager_Inventory(mongoclient=self.mongoclient,
                                               redisclient=self.redisclient)
예제 #4
0
 def __init__(self, username, vault_passwd=None, mongoclient=None):
     
     self.logger = logging.getLogger("ansible")
     self.yaml_mongocollect = username + '.ansible.yaml'
     self.temp_basedir = '/dev/shm/devops/ansible/yaml/'
     self.username = username
     self.vault_passwd = vault_passwd
     
     if mongoclient is None :
         self.mongoclient = Op_Mongo()
         self.logger.warn('无法继承,需要初始化mongodb连接')
     else :
         self.mongoclient = mongoclient
     
     if vault_passwd is None or not vault_passwd :
         self.this_cipher = None
         # self.logger.warn('没有提供vault密码,不加载加解密模块')
     else :
         self.logger.warn('提供vault密码,加载加解密模块')
         self.this_cipher = Using_AES256(vault_passwd, vault_header)
     
     self.vault_header = vault_header
예제 #5
0
파일: read.py 프로젝트: acmchen/Opsystem
    def __init__(self, oper, log_router=False, mongoclient=None):
        '''
        根据condition_dict读取所有的callback日志
        :parm
            condition_dict:查询条件
        '''

        self.logger = logging.getLogger("ansible")
        if mongoclient is None:
            self.mongoclient = Op_Mongo()
        else:
            self.mongoclient = mongoclient

        if not log_router:
            from library.storage.logging import Routing_Logging
            log_router = Routing_Logging()

        self.log_router = log_router
        self.collect = oper + '.ansible.callback'
        self.log_dict = {
            'level': 'info',
            'dest': 'mongo',
            'mongo': self.collect,
        }
예제 #6
0
파일: urls.py 프로젝트: zishuang951/lykops
from django.conf.urls import url
# from django.contrib import admin

from library.connecter.database.mongo import Op_Mongo
from library.connecter.database.redis_api import Op_Redis
# from lykops import settings
from lykops.ansible.execute import Exec
from lykops.ansible.options import Options
from lykops.ansible.report import Report
from lykops.ansible.yaml import Yaml
from lykops.sysadmin.inventory import Inventory
# from lykops.sysadmin.privacy import Privacy
from lykops.sysadmin.user import User
from lykops.views import Login

mongoclient = Op_Mongo()
redisclient = Op_Redis()

urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^$',
        User(mongoclient=mongoclient, redisclient=redisclient).summary,
        name='index'),
    url(r'^login.html',
        Login(mongoclient=mongoclient, redisclient=redisclient).login,
        name='login'),
    url(r'^logout.html',
        Login(mongoclient=mongoclient, redisclient=redisclient).logout,
        name='logout'),
    url(r'^user/create_admin',
        Login(mongoclient=mongoclient, redisclient=redisclient).create_admin,
예제 #7
0
class Base():
    def __init__(self, mongoclient=None, redisclient=None):
        '''
        这是用户管理部分的MVC中的C
        '''

        self.logger = logging.getLogger("lykops")
        self.userinfo_mongocollect = 'user.login.info'
        self.userinfo_rediskey = 'lykops:userinfo'
        self.privacy_mongocollect = 'user.privacy'
        if mongoclient is None:
            self.mongoclient = Op_Mongo()
            self.logger.warn('无法继承,需要初始化mongodb连接')
        else:
            self.mongoclient = mongoclient

        if redisclient is None:
            self.redisclient = Op_Redis()
            self.logger.warn('无法继承,需要初始化redis连接')
        else:
            self.redisclient = redisclient

        self.password_api = Manager_Password()
        self.expiretime = 60 * 60 * 24
        self.rediskey_prefix = 'lykops:'

    def get_userinfo(self, force=False, username=None):
        '''
        获取userinfo数据
        '''

        if force:
            self.logger.warn('强制删除用户信息缓存')
            self.redisclient.delete(self.userinfo_rediskey)

        result = self.redisclient.get(self.userinfo_rediskey, fmt='obj')
        if result[0] and (result[1] is not None or result[1]):
            userinfo = result[1]
        else:
            result = self.mongoclient.find(self.userinfo_mongocollect)
            if result[0]:
                userinfo = result[1]

                set_dict = {
                    'name': self.userinfo_rediskey,
                    'value': userinfo,
                    'ex': self.expiretime
                }
                self.redisclient.set(set_dict, fmt='obj')
            else:
                userinfo = {}

        if username is None:
            return userinfo
        else:
            try:
                for u_dict in userinfo:
                    if username == u_dict['username']:
                        us = u_dict
                    else:
                        continue
            except:
                us = {}

            try:
                return us
            except:
                return {}

    def verify_vaultpassword(self, username, vault_password):
        '''
        验证用户的vault密码是否正确
        :parm
            username:用户名
            vault_password:vault密码
        '''

        user_dict = self.get_userinfo(username=username)
        if not user_dict:
            content = '用户' + username + '不存在'
            self.logger.error(content)
            return (False, content)

        try:
            cipher_pwd = user_dict['vault_password']
        except:
            content = '从数据库中没有查询到用户' + username + '的vault密码'
            self.logger.error(content)
            return (False, content)

        result = self.password_api.verify(vault_password, cipher_pwd)
        if not result:
            content = '用户' + username + '输入的vault密码与数据库中vault密码不匹配'
            self.logger.error(content)
            return (False, content)
        else:
            content = '用户' + username + '输入的vault密码与数据库中vault密码匹配成功'
            # self.logger.info(content)
            return (True, content)

    def get_data(self,
                 username,
                 redis_key,
                 mongo_collect,
                 force=False,
                 mongoshare=True):
        '''
        获取用户数据
        :parm
            username:用户名
            redis_key:redis缓存key名
            mongo_collect:mongo的集合名
            force:强制刷新
        '''

        if force:
            self.logger.warn('强制删除指定缓存')
            self.redisclient.delete(redis_key)

        result = self.redisclient.get(redis_key, fmt='obj')
        if not result[0] or (result[0] and not result[1]):
            if mongoshare:
                result = self.mongoclient.find(
                    mongo_collect, condition_dict={'username': username})
            else:
                result = self.mongoclient.find(mongo_collect)

            if result[0]:
                data_dict = result[1]
                self.write_cache(redis_key, data_dict)
            else:
                self.logger.error('从数据库中查询数据失败,原因:' + result[1])
                return result
        else:
            data_dict = result[1]

        try:
            del data_dict['username']
        except:
            pass

        return (True, data_dict)

    def encryp_dict(self,
                    username,
                    vault_password,
                    data,
                    vault_list,
                    isverify=True):
        '''
        对用户的数据字典中的某些字段进行加密
        '''

        encryp_api = Using_AES256(vault_password, vault_header)
        if isverify:
            vault_result = self.verify_vaultpassword(username, vault_password)
            if not vault_result[0]:
                self.logger.error('加密用户' + username +
                                  '的指定数据时失败,原因:输入的vault密码与数据库中vault密码不匹配')
                return (False, '输入的vault密码与数据库中vault密码不匹配')

        if not vault_list:
            vault_list = data.keys()

        encryp_dict = {}
        for key, value in data.items():
            if not value:
                encryp_dict[key] = value

            if key in vault_list:
                result = encryp_api.encrypt(value)
                if result[0]:
                    encryp_dict[key] = result[1]
                else:
                    self.logger.error('加密用户' + username + '的指定数据时失败,键名' + key +
                                      '的值加密失败,原因:' + result[1])
                    return (False, '加密用户' + username + '的指定数据时失败,键名' + key +
                            '的值加密失败,' + result[1])
            else:
                if value == 'False':
                    value = False

                if value == 'True':
                    value = True

                isdigit = True
                if isinstance(value, str):
                    for t in value:
                        if t not in '0123456789':
                            isdigit = False

                if isdigit:
                    try:
                        value = int(value)
                    except:
                        pass

                encryp_dict[key] = value

        # content = '加密用户' + username + '的指定数据成功'
        # self.logger.info(content)
        return (True, encryp_dict)

    def decryp_dict(self,
                    username,
                    vault_password,
                    data,
                    vault_list,
                    isverify=True):
        '''
        对用户的数据字典中的某些字段进行解密
        '''

        encryp_api = Using_AES256(vault_password, vault_header)
        if isverify:
            vault_result = self.verify_vaultpassword(username, vault_password)
            if not vault_result[0]:
                self.logger.error('解密用户' + username +
                                  '的指定数据时失败,原因:输入的vault密码与数据库中vault密码不匹配')
                return (False, '输入的vault密码与数据库中vault密码不匹配')

        if not vault_list:
            vault_list = data.keys()

        decryp_dict = {}
        for key, value in data.items():
            if not value:
                decryp_dict[key] = value

            if key in vault_list:
                result = encryp_api.decrypt(value)
                if result[0]:
                    decryp_dict[key] = result[1]
                else:
                    self.logger.error('解密用户' + username + '的指定数据时失败,键名' + key +
                                      '的值加密失败,原因:' + result[1])
                    return (False, '解密用户' + username + '的指定数据时失败,键名' + key +
                            '的值加密失败,' + result[1])
            else:
                if value == 'False':
                    value = False

                if value == 'True':
                    value = True

                decryp_dict[key] = value

        # content = '解密用户' + username + '的指定数据成功'
        # self.logger.info(content)
        return (True, decryp_dict)

    def encryp_string(self, username, vault_password, data, isverify=True):
        '''
        对用户的数据进行加密
        '''

        encryp_api = Using_AES256(vault_password, vault_header)
        if isverify:
            vault_result = self.verify_vaultpassword(username, vault_password)
            if not vault_result[0]:
                self.logger.error('加密用户' + username +
                                  '数据时失败,原因:输入的vault密码与数据库中vault密码不匹配')
                return (False,
                        '加密用户' + username + '数据时失败,输入的vault密码与数据库中vault密码不匹配')

        result = encryp_api.encrypt(data)
        if result[0]:
            # content = '加密用户' + username + '数据成功'
            # self.logger.info(content)
            return (True, result[1])
        else:
            self.logger.error('加密用户' + username + '数据失败,原因:' + result[1])
            return (False, '加密用户' + username + '数据失败,' + result[1])

    def decryp_string(self, username, vault_password, data, isverify=True):
        '''
        对用户的数据进行解密
        '''

        decryp_api = Using_AES256(vault_password, vault_header)
        if isverify:
            vault_result = self.verify_vaultpassword(username, vault_password)
            if not vault_result[0]:
                self.logger.error('解密用户' + username +
                                  '数据时失败,原因:输入的vault密码与数据库中vault密码不匹配')
                return (False,
                        '解密用户' + username + '数据时失败,输入的vault密码与数据库中vault密码不匹配')

        result = decryp_api.decrypt(data)
        if result[0]:
            # content = '解密用户' + username + '数据成功'
            # self.logger.info(content)
            return (True, result[1])
        else:
            self.logger.error('解密用户' + username + '数据失败,原因:' + result[1])
            return (False, result[1])

    def change_vltpwd_dict(self,
                           username,
                           old_pwd,
                           new_pwd,
                           vault_dict,
                           vault_list,
                           isverify=False):
        '''
        修改用户的vault数据(字典)的vault密码
        '''

        try:
            del vault_dict['add_time']
        except:
            pass

        if not vault_list:
            vault_list = vault_dict.keys()

        # 不要使用encryp_dict和decryp_dict来更换密码,否则无法修改密码

        new_data = {}
        for key, value in vault_dict.items():
            if key in vault_list:
                result = self.decryp_string(username,
                                            old_pwd,
                                            value,
                                            isverify=isverify)
                if not result[0]:
                    self.logger.error('更改用户' + username +
                                      '的vault密码时失败,解密数据时出错,原因:' + result[1])
                    return (False, '更改用户' + username + '的vault密码时失败,解密数据时出错,' +
                            result[1])

                new_value = result[1]
                result = self.encryp_string(username,
                                            new_pwd,
                                            new_value,
                                            isverify=isverify)
                if not result[0]:
                    self.logger.error('更改用户' + username +
                                      '的vault密码时失败,解密后再次加密数据时出错,原因:' +
                                      result[1])
                    return (False, '更改用户' + username +
                            '的vault密码时失败,解密后再次加密数据时出错,' + result[1])

                new_data[key] = result[1]
            else:
                new_data[key] = value

        # content = '更改用户' + username + '的vault密码成功'
        # self.logger.info(content)
        return (True, new_data)

    def write_cache(self, redis_key, data, expire=60 * 60, ftm='obj'):
        try:
            self.logger.warn('强制删除缓存')
            self.redisclient.delete(redis_key)
        except:
            pass

        set_dict = {'name': redis_key, 'value': data, 'ex': expire}

        result = self.redisclient.set(set_dict, fmt=ftm)
        if result[0]:
            content = '写缓存成功'
            # self.logger.info(content)
            return (True, content)
        else:
            self.logger.info('写缓存失败,原因:' + result[1])
            return (False, '写缓存失败,' + result[1])
예제 #8
0
class Yaml_Base():
    def __init__(self, username, vault_passwd=None, mongoclient=None):
        
        self.logger = logging.getLogger("ansible")
        self.yaml_mongocollect = username + '.ansible.yaml'
        self.temp_basedir = '/dev/shm/devops/ansible/yaml/'
        self.username = username
        self.vault_passwd = vault_passwd
        
        if mongoclient is None :
            self.mongoclient = Op_Mongo()
            self.logger.warn('无法继承,需要初始化mongodb连接')
        else :
            self.mongoclient = mongoclient
        
        if vault_passwd is None or not vault_passwd :
            self.this_cipher = None
            # self.logger.warn('没有提供vault密码,不加载加解密模块')
        else :
            self.logger.warn('提供vault密码,加载加解密模块')
            self.this_cipher = Using_AES256(vault_passwd, vault_header)
        
        self.vault_header = vault_header
    
    
    def check_main(self, yaml_data):
        includefile_dict = {}
        roles_list = []
        log_prefix = '校验类型为main或者是full_roles的ansible yaml语法规则,'
        
        for data in yaml_data :
            if not isinstance(data, dict) :
                self.logger.error(log_prefix + '未通过语法检测,原因:可能不是ansible格式的yaml文件')
                return (False, '可能不是ansible格式的yaml文件')
            
            key_list = data.keys()
            # if not ('hosts' in key_list and ('tasks' in key_list or 'roles' in key_list)) and 'include' not in key_list:
            if not ('hosts' in key_list and ('tasks' in key_list or 'roles' in key_list)):
                self.logger.error(log_prefix + '未通过ansible原生语法检测,原因:缺少hosts、tasks或者roles等必要的字段')
                return (False, '未通过ansible原生语法检测,缺少hosts、tasks或者roles等必要的字段')
            
            for key, value in data.items() :
                if key == 'include' :
                    self.logger.error(log_prefix + '未通过本系统特定语法检测,原因:本系统禁止在入口文件中含有"- include:"字段。注:虽然原生ansible支持这样写')
                    return (False, '未通过本系统特定的语法检测,本系统禁止在入口文件中含有"- include:"字段')
                        
                if key == 'tasks' :
                    if not isinstance(value, (list, tuple)) :
                        self.logger.error(log_prefix + '未通过ansible原生语法检测,原因:tasks部分为空。')
                        return (False, '未通过ansible原生语法检测,tasks部分为空。')
                    
                    for v in value :
                        if not isinstance(v, dict) :
                            self.logger.error(log_prefix + '未通过ansible原生语法检测,原因:tasks部分异常。')
                            return (False, '未通过ansible原生语法检测,tasks部分异常。')
                        
                        for name , task in v.items() :
                            if name == 'include' :
                                result = self._isinclude(task)
                                if not result[0] :
                                    return result
                                    
                                includefile_dict[task] = 'tasks'
                                
                                '''
                                for file in task :
                                    result = self._isinclude(file)
                                    if not result[0] :
                                        return result
                                    
                                    includefile_dict[file] = 'tasks'
                                '''
                                    
                if key == 'roles' :
                    if not isinstance(value, (list, tuple)) :
                        self.logger.error(log_prefix + '未通过ansible原生语法检测,原因:roles部分为空。')
                        return (False, '未通过ansible原生语法检测,roles部分为空。')
                    
                    for v in value :
                        if not isinstance(v, dict) :
                            self.logger.error(log_prefix + '未通过ansible原生语法检测,原因:roles部分异常。')
                            return (False, '未通过ansible原生语法检测,roles部分异常。')
                        
                        kv = list(v.keys())
                        if not (len(kv) == 1 and 'role' in kv) :
                            self.logger.error(log_prefix + '未通过ansible原生语法检测,原因:roles部分缺少role。')
                            return (False, '未通过ansible原生语法检测,roles部分缺少role。')
                        
                        try :
                            roles_name = v['role']
                            if not self._isrolesname(roles_name):
                                self.logger.error(log_prefix + '未通过本系统特定语法检测,原因:roles名不符合本系统要求的,本系统要求roles只能是大小写、数字以及:。注:虽然原生ansible支持这样写。')
                                return (False, '未通过本系统特定语法检测,roles名不符合本系统要求的,本系统要求roles只能是大小写、数字以及:。')
                            
                            roles_list.append(roles_name)
                        except :
                            self.logger.error(log_prefix + '未通过语法检测,原因:roles部分异常。')
                            return (False, '未通过语法检测,roles部分异常。')
        
        self.logger.info(log_prefix + '通过语法检测')
        return (True, roles_list, includefile_dict)
        
            
    def check_include(self, yaml_data, file_type='main'):
        log_prefix = '校验类型为include的ansible yaml语法规则,'
        if file_type == 'main' :
            self.logger.error(log_prefix + '未通过本系统特定语法检测,原因:本系统禁止在入口文件中含有"- include:"字段。注:虽然原生ansible支持这样写。')
            return (False, '未通过本系统特定语法检测,本系统禁止在入口文件中含有"- include:"字段')
        
        if file_type == 'var' :
            if not isinstance(yaml_data, dict) :
                self.logger.error(log_prefix + '未通过ansible原生语法检测,原因:变量文件格式必须是键值对')
                return (False, '未通过ansible原生语法检测,变量文件格式必须是键值对')
            else :
                self.logger.info(log_prefix + '通过语法检测')
                return (True, '')
        
        for data in yaml_data :
            if not isinstance(data, dict) :
                self.logger.error(log_prefix + '未通过ansible原生语法检测,原因:语法错误')
                return (False, '未通过ansible原生语法检测,语法错误')
            
            if file_type != 'main' :
                deny_list = ('hosts', 'tasks', 'roles')
                key_list = data.keys()
                for deny in deny_list :
                    if deny in key_list :
                        self.logger.error(log_prefix + '未通过ansible原生语法检测,原因:含有非法字段' + deny)
                        return (False, '未通过ansible原生语法检测,含有非法字段' + deny)

            for key in data :
                if key == 'include' :
                    self.logger.error(log_prefix + '未通过本系统特定语法检测,原因:本系统不允许嵌套使用include。注:虽然原生ansible支持这样写。')
                    return (False, '未通过本系统特定语法检测,本系统不允许嵌套使用include')

        self.logger.info(log_prefix + '通过语法检测')
        return (True, '')
           
           
    def check_roles(self, content_dict):
        
        '''
        检测roles语法是否正确
        '''

        log_prefix = '校验类型为roles的ansible yaml语法规则,'
        if 'tasks' not in content_dict :
            self.logger.error(log_prefix + '未通过ansible原生语法检测,原因:tasks/main.yaml不存在')
            return (False, '未通过ansible原生语法检测,tasks/main.yaml不存在')

        include_dict = {}
        for this_dir , content in content_dict.items() :

            result = self.yaml_loader(content, data_type='data')
            if result[0] :
                yaml_data = result[-1]
            else :
                self.logger.error(log_prefix + this_dir + '/main.yaml转化成yaml数据时失败,原因:' + result[1])
                return (False, this_dir + '/main.yaml转化成yaml数据时失败,' + result[1])
            
            result = self.check_roles_singlefile(yaml_data, this_dir)
            if result[0] :
                include_dict.update(result[1])
            else :
                self.logger.error(log_prefix + this_dir + '/main.yaml未通过语法检测,原因:' + result[1])
                return (False, this_dir + '/main.yaml未通过语法检测,' + result[1])
        
        self.logger.info(log_prefix + '通过语法检测')
        return (True, include_dict)
           
           
    def check_roles_singlefile(self, yaml_data, this_dir):
        
        '''
        解析roles的每个文件
        :parm
            yaml_data:yaml数据
            this_dir:roles下的标准目录名
        '''

        include_dict = {}
        log_prefix = '校验' + this_dir + '/main.yaml语法规则,'
        if this_dir in ('handlers', 'tasks') :
            file_type = 'tasks'
        else :
            file_type = 'var'

        if this_dir == 'templates' :
            self.logger.info(log_prefix + '通过语法检测')
            return (True, include_dict)

        if file_type == 'var' :
            if isinstance(yaml_data, (list, tuple)) :
                return (False, '在role中' + this_dir + '文件不能含有键值对')
            else :
                self.logger.info(log_prefix + '通过语法检测')
                return (True, include_dict)
        
        if not isinstance(yaml_data, (list, tuple)) :
            return (False, '在role中' + this_dir + '文件语法错误')

        for data in yaml_data :
            if not isinstance(data, dict) :
                return (False, '在role中该文件不能含有键值对')

            for key, value in data.items() :
                if key == 'hosts' or key == 'tasks' or key == 'roles' :
                    return (False, '在role中' + this_dir + '/main.yaml文件不能含有' + key + '关键字')
                    
                if key == 'include':
                    if this_dir == 'handlers' :
                        return (False, '在role中' + this_dir + '/main.yaml文件不能含有' + key + '关键字')
                    else :
                        result = self._isinclude(value)
                        if not result[0] :
                            return result
                        
                        include_dict[value] = 'tasks'
        
        self.logger.info(log_prefix + '通过语法检测')
        return (True, include_dict)

                
    def yaml_loader(self, data, data_type='file'):
        
        '''
        将文件或者原始数据解析成yaml数据,如果是vault数据,将在这里解密
        :parm
            data:路径或者原始数据
            data_type:指定类型,文件或者原始数据
        '''
        
        
        if data_type == 'file' :
            log_prefix = '将yaml文件' + data + '的内容(必须为原始数据)解析为yaml格式的数据,'
            result = check_fileaccessible(data)
            if result[0] :
                filename = result[1]
            else :
                self.logger.error(log_prefix + '读取文件时失败,原因:' + result[1])
                return (False, '读取文件时失败,' + result[1])
            
            result = read_file(filename)
            if result[0] :
                content = result[1]
            else :
                self.logger.error(log_prefix + '读取文件时失败,原因:' + result[1])
                return (False, '读取文件时失败,' + result[1])
        else :
            log_prefix = '将原始yaml数据解析为yaml格式的数据,'
            content = data
            filename = ''
            # 是否写入文件中
        
        result = yaml_loader(content, data_type='data')
        if result[0] :
            yaml_data = result[1]
        else :
            self.logger.error(log_prefix + '解析失败,原因:' + result[1])
            return (False, '解析成yaml失败,' + result[1])
        
        if not isinstance(yaml_data, (dict, list, tuple)) :
            self.logger.error(log_prefix + '解析失败,原因:该文件内容不是ansible支持的yaml数据')
            return (False, '解析成yaml失败,该文件内容不是ansible支持的yaml数据')
        
        self.logger.info(log_prefix + '解析成功')
        return (True, filename, content, yaml_data)


    def write2db(self, name, content, yaml_type, describe=''):
    # def write2db(self, this_path, content, yaml_type, describe='', name=''):
        
        '''
        把yaml原始数据写入数据库中
        :parm
            this_path:通用该yaml(方式为roles或者include)的文件中写入的实际路径
            content:yaml文件原始数据(可能是字典,也可能为字符串)
            yaml_type:yaml类型
            name:yaml文件内容写入数据的名称
            describe:yaml文件内容写入数据的描述
            zhname:yaml文件内容写入数据的中文名称,很简短说明
        '''
        
        if not isinstance(name, str) :
            self.logger.error('将yaml原始数据写入数据库失败,原因:参数name必须为字符串')
            return (False, '参数name必须为字符串')

        log_prefix = '将名为' + name + '的yaml原始数据写入数据库,'
        result = self.get_name_list()
        if not result[0] :
            return result
        else :
            nametype_dict = result[1]
            if nametype_dict :
                try :
                    if name in nametype_dict[yaml_type] :
                        self.logger.error(log_prefix + '解析失败,原因:名称重复')
                        return (False, '名称重复,请修改名称在保存,谢谢')
                except :
                    pass
        
        insert_data = {
            'name' : name,
            'uuid' : str(uuid.uuid4()),
            # UUID不能作为roles或include名,只能用于查找标识
            'content' : content,
            'type' : yaml_type,
            'describe' :describe,
            'lastedit_ts' : 0
            }
        
        insert_dict = {
            'collect' : self.yaml_mongocollect,
            'data' : insert_data
            }
        
        result = self.mongoclient.insert(insert_dict, addtime=True)
        self.logger.info('将名为' + name + '的yaml原始数据写入数据库成功')
        return result

          
    def edit2db(self, uuid_str, content, describe='', name=''):
        
        '''
        把修改后的yaml原始数据写入数据库中
        :parm
            uuid_str:需要修改的UUID
            content:yaml文件原始数据(可能是字典,也可能为字符串)
            name:yaml文件内容写入数据的名称
            describe:yaml文件内容写入数据的描述
            zhname:yaml文件内容写入数据的中文名称,很简短说明
        '''

        log_prefix = '编辑数据库中uuid为' + uuid_str + '的yaml数据,'
        if not isinstance(name, str) :
            self.logger.error('编辑数据库中uuid为' + uuid_str + '的yaml数据失败,原因:参数name必须为字符串')
            return (False, '参数name必须为字符串')
        
        if not re.search('^[a-z|A-Z|0-9]{8}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{12}$', uuid_str) :
            self.logger.error(log_prefix + '参数提供错误,原因:参数uuid不是一个标准的UUID,标准的UUID格式为^[a-z|A-Z|0-9]{8}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{12}$')
            return (False, '参数uuid不是一个标准的UUID,标准的UUID格式为^[a-z|A-Z|0-9]{8}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{12}$')
        
        update_data = {'content' : content}
        
        result = self.read2db(uuid_str, word_field='uuid')
        if result[0] : 
            try :
                yaml_type = result[1]['type']
                old_name = result[1]['name']
            except :
                return (False, '从数据库读取时出错')
        else :
            return result
        
        if name and old_name != name :
            result = self.get_name_list()
            if not result[0] :
                return result
            else :
                nametype_dict = result[1]
                if nametype_dict :
                    if name in nametype_dict[yaml_type] :
                        self.logger.error(log_prefix + '解析失败,原因:名称重复')
                        return (False, '名称重复,请修改名称在保存,谢谢')
            update_data['name'] = name
            
        if describe and isinstance(describe, str):
            update_data['describe'] = describe

        update_data['lastedit_ts'] = time.time()
        update_dict = {
            'collect' : self.yaml_mongocollect,
            'data' : {"$set": update_data}
            }
        
        result = self.mongoclient.update({'uuid':uuid_str}, update_dict, addtime=False)
        self.logger.info(log_prefix + '写入数据库成功')
        return result
    
            
    def _write2file(self, content, filename):
        
        '''
        写入文件,如果处理加密数据等,应该放在这里
        :parm
            content:写入的内容
            filename:指定文件名
        '''
        
        if not isinstance(content, str) :
            self.logger.error('将yaml原始数据写入文件' + filename + '失败,原因:参数错误,content必须为字符串')
            return (False, '参数错误,content必须为字符串')
                
        result = write_file(filename , 'w' , content, force=True)
        if result[0] :
            self.logger.error('将yaml原始数据写入文件' + filename + '成功')
            return (True, filename)
        else :
            self.logger.error('将yaml原始数据写入文件' + filename + '失败,原因:' + result[1])
            return (False, '写入文件失败,' + result[1])


    def _isrolesname(self, roles_name):
        
        '''
        判断传入字符串是否符合本系统要求的roles名
        :param 
            word: 待判断字符串
        :return: 
            True:包含 
            False:不包含
        '''
        
        word_list = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789:'
    
        if not isinstance(roles_name, str) :
            return False
        
        for s in roles_name :
            if s not in word_list :
                return False
    
        return True


    def _isinclude(self,filename):
        
        '''
        判断传入字符串是否符合本系统要求的include
        :param 
            word: 待判断字符串
        :return: 
            True:包含 
            False:不包含
        '''
        
        if re.search('^/', filename) :
            self.logger.error('检测include文件名是否符合本系统要求,' + filename + '不符合,原因:include文件不能为绝对路径')
            return (False, 'include文件不能为绝对路径') 
                                    
        if re.search('^main\.', os.path.basename(filename)) :
            self.logger.error('检测include文件名是否符合本系统要求,' + filename + '不符合,原因:include文件名不能含有"main."字符')
            return (False, 'include文件名不能含有"main."字符')
        
        return (True, '')


    def get_abs(self):
        
        '''
        获取摘要信息
        '''
        
        get_field_list = ['name', 'uuid' , 'type' , 'describe']
        result = self.mongoclient.find(self.yaml_mongocollect, get_field=get_field_list)
        return result
        
        
    def get_name_list(self):
        
        '''
        获取DB中的所有name和yaml_type
        '''
        
        get_field_list = ['name', 'type']
        result = self.mongoclient.find(self.yaml_mongocollect, get_field=get_field_list)
        
        if not result[0] :
            self.logger.error('从数据库中获取所有yaml数据的name和yaml_type时发生错误,原因:' + result[1])
            return (False, '从数据库中获取所有yaml数据的name和yaml_type时发生错误,原因:' + result[1])
        
        name_type_dict = {}
        name_list = result[1]
        for name_dict in name_list :
            name = name_dict['name']
            yaml_type = name_dict['type']
            
            if yaml_type not in name_type_dict :    
                name_type_dict[yaml_type] = []
                name_type_dict[yaml_type].append(name)
            else :
                name_type_dict[yaml_type].append(name)
                    
        return (True, name_type_dict)
        
        
    def read2db(self, word, word_field='name'):
        
        '''
        从数据库读取
        :parm
            word:关键字
            word_field:根据那个字段(name或者UUID)作为关键字查找
        '''
        
        if word is None or not word or not isinstance(word, str) :
            self.logger.error('从数据库通过关键字查找的yaml数据失败,原因:参数word必须为不为空字符串')
            return (False, '参数word必须为不为空字符串')

        if re.search('^[a-z|A-Z|0-9]{8}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{4}-[a-z|A-Z|0-9]{12}$', word) :
            word_field = 'uuid'

        if word_field == 'uuid' :
            result = self.mongoclient.find(self.yaml_mongocollect, condition_dict={word_field:word})
        elif word_field in ('name') :
            result = self.mongoclient.find(self.yaml_mongocollect, limits=1, condition_dict={word_field:word}, sort_dict={'add_time':-1})
        else :
            result = self.mongoclient.find(self.yaml_mongocollect, limits=1, condition_dict={word_field:word}, sort_dict={'add_time':-1})
                
        if not result[0] :
            self.logger.error('从数据库查找关键字类型为' + word_field + ',关键字为' + word + '的yaml数据失败,原因:' + str(result[1]))
            return (False, '查询失败,' + str(result[1]))
        
        try :
            get_dict = result[1][0]
            return (True, get_dict)
        except :
            if not result[1] :
                self.logger.error('从数据库查找关键字类型为' + word_field + ',关键字为' + word + '的yaml数据失败,原因:查询结果为空')
                return (False, '查询结果为空')
            else :
                self.logger.error('从数据库查找关键字类型为' + word_field + ',关键字为' + word + '的yaml数据失败,原因:查询结果数据类型异常')
                return (False, '查询结果数据类型异常')
        

    def data2file(self, content, this_path='', yaml_type='main', name='main'):
        
        '''
        写入临时文件
        :parm
            content:yaml的原始内容
            this_path:写入的目录,如果提供按照指定目录写入,如果不指定随机目录
            yaml_type:yaml类型。main、include、roles、full_roles四种
            name:用于确认include和roles的文件名
        '''
        
        if not this_path or not re.search('^/', this_path):
            this_path = self.temp_basedir + '/' + random_str() + str(int(time.time())) + '/'
        
        def type_roles(content_dict, roles_name):
            
            '''
            专用于类型为roles的数据写入
            '''
            
            for this_dir in content_dict :
                # roles_path = this_path + '/roles/' + os.path.basename(roles_name) + '/' + this_dir
                roles_path = this_path + '/roles/' + roles_name + '/' + this_dir
                
                if this_dir == 'templates'  :
                    for temp_file , temp_content in content_dict[this_dir].items() :
                        filename = roles_path + '/' + temp_file
                        result = self._write2file(temp_content, filename)
                        if not result[0] :
                            self.logger.error('将roles名为' + roles_name + '中的文件名为' + this_dir + '/' + temp_file + 'yaml数据内容写入文件' + filename + '失败,' + result[1])
                            return (False, '将roles名为' + roles_name + '中的文件名为' + this_dir + '/' + temp_file + 'yaml数据内容写入文件' + filename + '失败,' + result[1])
                        else :
                            self.logger.info('将roles名为' + roles_name + '中的文件名为' + this_dir + '/' + temp_file + 'yaml数据内容写入文件' + filename + '成功')
                else :
                    filename = roles_path + '/main.yaml'
                    result = self._write2file(content_dict[this_dir], filename)
                    if not result[0] :
                        self.logger.error('将roles名为' + roles_name + '中的文件名为' + this_dir + '/main.yaml数据内容写入文件' + filename + '失败,' + result[1])
                        return (False, '将roles名为' + roles_name + '中的文件名为' + this_dir + '/main.yaml数据内容写入文件' + filename + '失败,' + result[1])
                    else :
                        self.logger.info('将roles名为' + roles_name + '中的文件名为' + this_dir + '/main.yaml数据内容写入文件' + filename + '成功')
            return (True, this_path)
        
        log_prefix = '将yaml数据内容写入文件'
        if isinstance(content, str) :
            filename = this_path + name + '.yaml'
            result = self._write2file(content, filename)
            return result
        
        if not isinstance(content, dict) :
            self.logger.error(log_prefix + '失败,原因:数据写入数据库时出现错误')
            return (False, '数据写入数据库时出现错误')
        
        if yaml_type == 'roles' :
            result = type_roles(content, name)
        else :
            try :
                roles_dict = content['roles']
                for roles_name in roles_dict :
                    roles_content_dict = roles_dict[roles_name]
                    result = type_roles(roles_content_dict, roles_name)
            except Exception as e :
                print(e)
                roles_dict = {}
                
            try :
                include_dict = content['include']
                for incluce_file , incluce_content in include_dict.items() :
                    filename = this_path + '/' + incluce_file
                    result = self._write2file(incluce_content, filename)
                    if not result[0] :
                        self.logger.error(log_prefix + '失败,路径为' + filename + ',原因:' + str(result[1]))
                        return (False, log_prefix + '失败,路径为' + filename + ',' + str(result[1]))
            except Exception as e :
                print(e)
                include_dict = {}
    
            try :
                main_content = content['main']
                filename = this_path + '/main.yaml'
                result = self._write2file(main_content, filename)
                if not result[0] :
                    self.logger.error(log_prefix + '失败,路径为' + filename + ',原因:' + str(result[1]))
                    return (False, log_prefix + '失败,路径为' + filename + ',原因:' + str(result[1]))
            except Exception as e :
                print(e)
                main_content = ''
            
        self.logger.info(log_prefix + '成功,路径为' + this_path)
        return (True, this_path)
예제 #9
0
파일: read.py 프로젝트: acmchen/Opsystem
class Parse_Cblog():
    def __init__(self, oper, log_router=False, mongoclient=None):
        '''
        根据condition_dict读取所有的callback日志
        :parm
            condition_dict:查询条件
        '''

        self.logger = logging.getLogger("ansible")
        if mongoclient is None:
            self.mongoclient = Op_Mongo()
        else:
            self.mongoclient = mongoclient

        if not log_router:
            from library.storage.logging import Routing_Logging
            log_router = Routing_Logging()

        self.log_router = log_router
        self.collect = oper + '.ansible.callback'
        self.log_dict = {
            'level': 'info',
            'dest': 'mongo',
            'mongo': self.collect,
        }

    def parse(self, uuid_str):
        '''
        根据uuid_str读取callback日志
        '''

        log_prefix = '查询uuid为' + uuid_str + '的ansible任务执行报表'
        result = self.log_router.read(condition_dict={'uuid': uuid_str},
                                      log_dict=self.log_dict,
                                      limit=0,
                                      lastest_field=False)
        self.readlog_list = result[1]
        if not result[0]:
            self.logger.error(log_prefix + '失败,原因:' + result[1])
            return (False, log_prefix + '失败,' + result[1])

        try:
            name = self.readlog_list[0]['name']
            exec_mode = self.readlog_list[0]['mode']
            describe = self.readlog_list[0]['describe']
            options = self.readlog_list[0]['options']
            # create_time = self.readlog_list[0]['create_time']
            create_date = self.readlog_list[0]['create_date']
            inventory_content = self.readlog_list[0]['inventory_content']
            create_ts = self.readlog_list[0]['add_time']
            finish_ts = self.readlog_list[-1]['add_time']
        except Exception as e:
            self.logger.error(log_prefix + '失败,原因:该任务还没有开始执行或者数据错误,' + str(e))
            return (False, '该任务还没有开始执行或者数据错误')

        pattern = self.readlog_list[0].get('pattern', None)
        module_name = self.readlog_list[0].get('module_name', None)
        module_args = self.readlog_list[0].get('module_args', None)
        yaml_content = self.readlog_list[0].get('yaml_content', None)
        play = self.readlog_list[0].get('play', {})
        task = self.readlog_list[0].get('task', {})

        newlog_dict = {
            'name': name,
            'mode': exec_mode,
            'describe': describe,
            'create_time': timestamp2datetime(create_ts),
            'create_date': create_date,
            'options': options,
            'uuid': uuid_str,
            'inventory_content': inventory_content,
            'end_time': timestamp2datetime(finish_ts),
            'duration': round((finish_ts - create_ts), 3),
        }

        if exec_mode == 'adhoc':
            newlog_dict['pattern'] = pattern
            newlog_dict['module_name'] = module_name
            newlog_dict['module_args'] = module_args
        else:
            newlog_dict['yaml_content'] = yaml_content

        get_field_list = ['uuid', 'play_id', 'task_id']
        result = self.mongoclient.group_by(self.collect, get_field_list)
        if not result[0]:
            self.logger.error(log_prefix + '失败,原因:该任务还没有开始执行或者数据错误,' +
                              result[1])
            return (False, '该任务还没有开始执行或者数据错误')

        tempplay_dict = {}
        for playid in result[1]:
            if playid['uuid'] == uuid_str:
                play_id = playid['play_id']
                task_id = playid.get('task_id', '')
                if task_id == '':
                    continue
            else:
                continue

            if play_id not in tempplay_dict:
                tempplay_dict[play_id] = []

            taskid_list = tempplay_dict[play_id]
            taskid_list.append(task_id)
            taskid_list = tempplay_dict[play_id]
            taskid_list = list(set(taskid_list))
            taskid_list = sorted(taskid_list)
            # 对taskid执行先后顺序排序
            tempplay_dict[play_id] = taskid_list

        playid_dict = {}
        for play_id in sorted(tempplay_dict):
            playid_dict[play_id] = tempplay_dict[play_id]
            # 对play执行先后顺序排序

        play_dict = {}
        # 下面这个循环用于:根据play_id获取下面所有的task_id,并获取的每个task_id的最后日志和执行结果信息
        for playid, taskid_list in playid_dict.items():
            play_dict[playid] = {}
            for taskid in taskid_list:
                task_list = []
                for line in self.readlog_list:
                    if line['play_id'] == playid and line.get('task_id',
                                                              '') == taskid:
                        summary = line.get('summary', {})
                        if not summary:
                            task_list.append(line)

                last_log = task_list[-1]
                # 求这个任务执行的最后一条日志
                play_dict[playid]['play'] = last_log.get('play', {})
                play_dict[playid]['summary'] = summary

                task_dict = {
                    'task': last_log.get('task', {}),
                    'detail': last_log.get('detail', {}),
                }

                try:
                    play_dict[playid]['task'][taskid] = task_dict
                except:
                    play_dict[playid]['task'] = {}
                    play_dict[playid]['task'][taskid] = task_dict

        if not play_dict or not isinstance(play_dict, dict):
            self.logger.error(log_prefix + '失败,原因:该任务还没有开始执行或者查询条件错误,' +
                              result[1])
            return (False, {'result': '该任务还没有开始执行或者查询条件错误'})

        result_dict = {}
        for play_uuid, logline in play_dict.items():
            result_dict[play_uuid] = {}
            summary = logline.get('summary', {})
            task_dict = logline.get('task', {})

            if 'tasks' not in result_dict[play_uuid]:
                result_dict[play_uuid]['tasks'] = {}

            play = logline.get('play', {})
            pattern = play.get('name', {})

            for task_id, line in task_dict.items():
                task = line.get('task', {})
                task_name = task.get('name', '')
                taskmodule = task.get('module', '')
                # task_args = task.get('args', {})
                if exec_mode == 'playbook' and task_name not in result_dict[
                        play_uuid]['tasks']:
                    result_dict[play_uuid]['tasks'][task_name] = {}
                    new_task = {
                        'module': task['module'],
                    }
                    result_dict[play_uuid]['tasks'][task_name][
                        'tasks'] = new_task

                detail = line.get('detail', {})
                if not isinstance(detail, dict) or not detail:
                    continue

                for host, value in detail.items():
                    end_ts = value['end_ts']
                    start_ts = value['start_ts']
                    duration = end_ts - start_ts
                    duration = round(duration, 2)
                    '''
                    if taskmodule == 'yum' and 'invocation' in value :
                        # 在yum模块中,在没有使用循环的情况下,value也含有results的key
                        results = [value]
                    else :
                        results = value.get('results', {})
                        
                    if results :
                        data_list = results
                    else :
                        data_list = [value]
                        
                    # data_list = [value]
                    '''
                    data_list = [value]

                    for data in data_list:

                        from library.connecter.ansible.callback.module import Parse_Result
                        parse_module = Parse_Result()
                        if taskmodule == 'command':
                            result = parse_module.command(data, task)
                        elif taskmodule == 'yum':
                            if 'invocation' in data:
                                result = parse_module.yum(data, task)
                            else:
                                try:
                                    temp_dict = data['results'][0]
                                    del data['results']
                                    data.update(temp_dict)
                                    result = parse_module.yum(data, task)
                                except:
                                    self.logger.error(data)
                                    result = parse_module.common_module(
                                        data, task, {})
                        elif taskmodule == 'service' or taskmodule == 'systemd':
                            result = parse_module.service(data, task)
                        elif taskmodule == 'script':
                            result = parse_module.script(data, task)
                        elif taskmodule == 'cron':
                            result = parse_module.cron(data, task)
                        elif taskmodule == 'user':
                            result = parse_module.user(data, task)
                        elif taskmodule == 'copy':
                            result = parse_module.copy(data, task)
                        elif taskmodule == 'get_url':
                            result = parse_module.get_url(data, task)
                        elif taskmodule == 'raw':
                            result = parse_module.command(data, task)
                        else:
                            result = parse_module.common_module(data, task, {})

                        if taskmodule == '':
                            print(result)

                        if exec_mode == 'playbook':
                            try:
                                del result['模块名']
                            except:
                                pass

                            if 'detail' not in result_dict[play_uuid]['tasks'][
                                    task_name]:
                                result_dict[play_uuid]['tasks'][task_name][
                                    'detail'] = {}

                            result_dict[play_uuid]['tasks'][task_name][
                                'detail'][host] = result
                            result_dict[play_uuid]['pattern'] = pattern
                        else:
                            try:
                                del result['模块名']
                                del result_dict[play_uuid]
                            except:
                                pass
                            result_dict[host] = result

            if exec_mode == 'playbook':
                result_dict[play_uuid]['summary'] = {}

                if isinstance(summary, dict):
                    for host in summary:
                        ok = summary[host].get('ok', 0)
                        failures = summary[host].get('failures', 0)
                        unreachable = summary[host].get('unreachable', 0)
                        changed = summary[host].get('changed', 0)
                        skipped = summary[host].get('skipped', 0)

                        if ok == 0:
                            if unreachable == 1:
                                summary_str = '该任务在该主机上执行失败,无法连接远程主机'
                            else:
                                summary_str = '该任务在该主机上执行失败,失败数为' + str(
                                    failures) + ',跳过数为' + str(
                                        skipped) + ',可能产生变化数为' + str(changed)
                        else:
                            summary_str = '该任务在该主机上执行部分或者全部成功,成功数为' + str(
                                ok) + ',失败数为' + str(failures) + ',跳过数为' + str(
                                    skipped) + ',可能产生变化数为' + str(changed)
                        '''
                        result_dict[play_uuid]['summary'][host] = summary[host]
                        原文输出
                        '''
                        result_dict[play_uuid]['summary'][host] = summary_str

                if not result_dict[play_uuid]['summary']:
                    result_dict[play_uuid]['summary'] = '该任务还没有执行完成'

        newlog_dict['exec_result'] = result_dict
        self.logger.info(log_prefix + '成功')
        return (True, newlog_dict)

    def get_abs(self):
        '''
        获取该用户下所有的执行任务的摘要
        '''

        get_field_list = [
            'name', 'uuid', 'mode', 'create_time', 'describe', 'create_date'
        ]
        result = self.mongoclient.group_by(self.collect, get_field_list)
        if not result[0]:
            self.logger.error('ansible任务执行报表清单查询失败,原因:' + result[1])
            return result

        work_list = result[1]
        if len(work_list) == 0:
            self.logger.warn('ansible任务执行报表清单为空')
            return (True, [])

        date_list = []
        for work in work_list:
            create_date = work['create_time']
            if create_date not in date_list:
                date_list.append(create_date)

        date_list = sorted(date_list)
        date_list.reverse()

        new_list = []
        for date_str in date_list:
            for work_dict in work_list:
                if date_str == work_dict['create_time']:
                    new_list.append(work_dict)

        return (True, new_list)
예제 #10
0
class Logging_Mongo():
    def __init__(self):
        '''
        该class用于写日志到mongodb服务器中
        __init__()用于初始化mongo
        '''

        from library.connecter.database.mongo import Op_Mongo
        self.mongoclient = Op_Mongo(dest='log')
        self.default_log_dict = log_category_dict['default']

    def write(self, content, oper, log_dict={}):
        '''
        写入mongo数据库
        :参数
            log_dict : 存储信息
            oper : 操作者
            content : 日志内容
            isdubug:是否为debug日志
        :返回
            一个元组,(False,原因)或者(True, 结果)
        '''

        if not log_dict or not isinstance(log_dict, dict):
            log_dict = self.default_log_dict

        try:
            dest = log_dict['dest']
            if dest != 'mongo':
                level = self.default_log_dict['level']
                collect = self.default_log_dict['mongo']
            else:
                level = log_dict['level']
                if level not in level_list:
                    level = self.default_log_dict['level']

                collect = log_dict['mongo']
        except Exception as e:
            return (False, str(e))

        if not oper:
            oper = 'unknown'

        if not content:
            return (False, '日志内容为空!!!!')

        msg_dict = {}

        if isinstance(content, dict):
            msg_dict.update(content)
        else:
            msg_dict['content'] = content

        insert_dict = {'collect': collect, 'data': msg_dict}

        result = self.mongoclient.insert(insert_dict, addtime=True)
        return result

    def read(self,
             get_field=[],
             condition_dict={},
             log_dict={},
             limit=0,
             lastest_field=False):
        '''
        读取mongo数据库的日志
        :参数
            log_dict : 日志存储信息
            condition_dict : 查询条件
            get_field_list : 获取字段列表
            limit : 限制获取多少条数据
            lastest_field : 获取该字段最新一条数据
        '''

        if log_dict == {} or not log_dict or not isinstance(log_dict, dict):
            return (False, '参数log_dict配置错误,必须是一个不为空的字典')

        if condition_dict == {} or not condition_dict or not isinstance(
                condition_dict, dict):
            return (False, '参数condition_dict必须是一个不为空的字典,查询条件')

        if not isinstance(get_field, (list, tuple, dict)):
            get_field = []

        try:
            collect = log_dict['mongo']
        except Exception as e:
            return (False, '参数log_dict配置错误,提供的内容为' + str(log_dict) + ',失败原因为' +
                    str(e))

        try:
            limit = int(limit)
        except:
            limit = 0

        if lastest_field:
            limit = 0

        result = self.mongoclient.find(collect,
                                       get_field=get_field,
                                       condition_dict=condition_dict,
                                       limits=limit,
                                       sort_dict={'add_time': 1})

        if not result[0]:
            return result

        content_list = result[1]
        content_len = len(content_list)
        if content_len == 0:
            return (True, [])
        elif content_len == 1:
            return (True, [content_list[0]])
        else:
            if not lastest_field:
                return (True, content_list)

        results = ''
        lastest_time = 0.0
        for line in content_list:
            if lastest_field in line:
                addtime = line[lastest_field]

                try:
                    addtime = float(addtime)
                except:
                    addtime = str(addtime)
                    from library.utils.time_conv import datetime2timestamp
                    addtime = datetime2timestamp(addtime)

                if not addtime:
                    addtime = 0.0
                else:
                    addtime = float(addtime)
                    if addtime >= lastest_time:
                        lastest_time = addtime
                        results = line

        if results == '':
            return (True, [content_list[-1]])

        return (True, [results])
예제 #11
0
 def __init__(self, mongoclient=None, redisclient=None):
     
     self.logger = logging.getLogger("devops")
     if mongoclient is None :
         self.mongoclient = Op_Mongo()
         self.logger.warn('无法继承,需要初始化mongodb连接')
     else :
         self.mongoclient = mongoclient
         
     if redisclient is None :
         self.redisclient = Op_Redis()
         self.logger.warn('无法继承,需要初始化redis连接')
     else :
         self.redisclient = redisclient
 
     self.redis_key_prefix = 'devops:'
     self.expiretime = 60 * 60 * 24
     
     self.uridict = {
         '/':{'name':'首页', 'nav':False, 'referer' : True, 'level':0, 'user_level':0,'parent':'/'},
         '/login.html':{'name':'登陆', 'nav':False, 'referer' : False, 'level':1, 'user_level':0,'parent':'/'},
         '/logout.html':{'name':'退出', 'nav':False, 'referer' : False, 'level':1, 'user_level':0,'parent':'/'},
         
         '/user/':{'name':'用户管理', 'nav':True, 'referer' : True, 'level':1, 'user_level':2,'parent':'/'},
         '/user/create_admin':{'name':'创建管理员', 'nav':False, 'referer' : True, 'level':2, 'user_level':2,'parent':'/user/'},
         '/user/detail':{'name':'用户信息', 'nav':False, 'referer' : True, 'level':2, 'user_level':2,'parent':'/user/'},
         '/user/list':{'name':'用户列表', 'nav':False, 'referer' : True, 'level':2, 'user_level':2,'parent':'user/'},
         '/user/add':{'name':'新增用户', 'nav':False, 'referer' : True, 'level':2, 'user_level':2,'parent':'/user/'},
         '/user/edit':{'name':'编辑用户', 'nav':False, 'referer' : True, 'level':2, 'user_level':2,'parent':'/user/'},
         '/user/chgpwd':{'name':'修改用户登陆密码', 'nav':False, 'referer' : True, 'level':2, 'user_level':2,'parent':'/user/'},
         '/user/chgpvltwd':{'name':'修改用户机密密码 ', 'nav':False, 'referer' : True, 'level':2, 'user_level':2,'parent':'/user/'},
         '/user/del':{'name':'删除用户', 'nav':False, 'referer' : False, 'level':2, 'user_level':2,'parent':'/user/'},
         '/user/disable':{'name':'禁用用户', 'nav':False, 'referer' : False, 'level':2, 'user_level':2,'parent':'/user/'},
         '/user/enable':{'name':'启用用户', 'nav':False, 'referer' : False, 'level':2, 'user_level':2,'parent':'/user/'},
         
         # '/privacy/' :{'name':'隐私数据管理', 'nav':True, 'referer' : True, 'level':1, 'parent':'/'},
         # '/privacy/detail' :{'name':'查看隐私数据', 'nav':False, 'referer' : True, 'level':2, 'parent':'/privacy/'},
         # '/privacy/edit' :{'name':'编辑隐私数据', 'nav':False, 'referer' : True, 'level':2, 'parent':'/privacy/'},
         
         '/inventory/' :{'name':' 主机管理', 'nav':True, 'referer' : True, 'level':1, 'user_level':0,'parent':'/'},
         '/inventory/list' :{'name':' 主机管理', 'nav':False, 'referer' : True, 'level':2, 'user_level':0,'parent':'/inventory/'},
         '/inventory/add' :{'name':' 增加主机', 'nav':False, 'referer' : True, 'level':2, 'user_level':0,'parent':'/inventory/'},
         '/inventory/edit' :{'name':' 编辑主机', 'nav':False, 'referer' : True, 'level':2, 'user_level':0,'parent':'/inventory/'},
         '/inventory/detail' :{'name':' 主机详细信息', 'nav':False, 'referer' : True, 'level':2, 'user_level':0,'parent':'/inventory/'},
         
         '/ansible/' :{'name':'ansible', 'nav':True, 'referer' : True, 'level':1, 'user_level':0,'parent':'/'},
         '/ansible/exec/adhoc' :{'name':'执行临时任务', 'nav':True, 'referer' : True, 'level':2, 'user_level':0,'parent':'/ansible/'},
         '/ansible/exec/playbook' :{'name':'执行playbook任务', 'nav':True, 'referer' : True, 'level':2, 'user_level':1,'parent':'/ansible/'},
         
         '/ansible/option/' :{'name':'查看配置', 'nav':True, 'referer' : True, 'level':2, 'user_level':0,'parent':'/ansible/'},
         '/ansible/option/detail' :{'name':'查看配置', 'nav':True, 'referer' : True, 'level':3, 'user_level':0,'parent':'/ansible/option/'},
         '/ansible/option/edit' :{'name':'编辑配置', 'nav':False, 'referer' : True, 'level':3, 'user_level':0,'parent':'/ansible/option/'},
         
         '/ansible/yaml/' :{'name':'yaml数据列表', 'nav':True, 'referer' : True, 'level':2, 'user_level':1,'parent':'/ansible/'},
         '/ansible/yaml/list' :{'name':'yaml数据列表', 'nav':False, 'referer' : True, 'level':3, 'user_level':1,'parent':'/ansible/yaml/'},
         '/ansible/yaml/add' :{'name':'新增yaml数据', 'nav':False, 'referer' : False, 'level':3, 'user_level':1,'parent':'/ansible/yaml/'},
         '/ansible/yaml/edit' :{'name':'编辑yaml数据', 'nav':False, 'referer' : True, 'level':3, 'user_level':1,'parent':'/ansible/yaml/'},
         '/ansible/yaml/detail' :{'name':'查看yaml数据', 'nav':False, 'referer' : True, 'level':3, 'user_level':1,'parent':'/ansible/yaml/'},
         '/ansible/yaml/import' :{'name':'导入yaml数据', 'nav':False, 'referer' : True, 'level':3, 'user_level':1,'parent':'/ansible/yaml/'},
         
         '/ansible/report/' :{'name':'报告', 'nav':True, 'referer' : True, 'level':2, 'user_level':0,'parent':'/ansible/'},
         '/ansible/report/list' :{'name':'报告列表', 'nav':False, 'referer' : True, 'level':3, 'user_level':0,'parent':'/ansible/report/'},
         '/ansible/report/detail' :{'name':'单个报告详细信息', 'nav':False, 'referer' : True, 'level':3, 'user_level':0,'parent':'/ansible/report/'},
         
         }
예제 #12
0
    def __init__(self,
                 exec_mode,
                 work_name,
                 username,
                 options_dict,
                 describe,
                 mongoclient=None):
        '''
        ansible的基类,为adhoc、playbook等父类
        :parm:
            exec_mode:ansible工作类型,接受adhoc、palybook等
            work_name:该任务的名称,用于日志
            username:执行者
            options_dict:该任务的特定设置
            mongoclient:初始化mongo连接类
        '''

        self.logger = logging.getLogger("ansible")
        if exec_mode in ('adhoc', 'playbook'):
            self.exec_mode = exec_mode
        else:
            self.logger.warn(
                '正在准备执行ansible任务,准备工作失败,原因:参数exec_mode必须是adhoc或者是playbook')
            return (False, '参数exec_mode必须是adhoc或者是playbook')

        if isinstance(work_name, str) and work_name:
            self.work_name = work_name
        else:
            self.logger.warn('正在准备执行ansible任务,准备工作失败,原因:参数work_name必须是非字符串')
            return (False, '参数work_name必须是非字符串')

        if isinstance(username, str) and username:
            self.username = username
        else:
            self.logger.warn('正在准备执行ansible任务,准备工作失败,原因:参数username必须是非字符串')
            return (False, '参数username必须是非字符串')

        if isinstance(options_dict, dict) and options_dict:
            self.options_dict = options_dict
        else:
            self.logger.warn('正在准备执行ansible任务,准备工作失败,原因:参数options_dict必须是非空字典')
            return (False, '参数options_dict必须是非空字典')

        if mongoclient is None:
            self.mongoclient = Op_Mongo()
        else:
            self.mongoclient = mongoclient

        self.work_uuid = str(uuid.uuid4())
        self.log_router = Routing_Logging()
        self.describe = describe

        if exec_mode == 'adhoc':
            self.log_prefix = '正在执行用户' + username + '的名为' + work_name + 'uuid为' + self.work_uuid + '的ansible临时任务,'
        else:
            self.log_prefix = '正在执行用户' + username + '的名为' + work_name + 'uuid为' + self.work_uuid + '的ansible-playbook任务,'

        # 下面是加载和初始化相关类
        self._parse_options()
        self.passwords = {
            'conn_pass': self.options.ask_pass,
            'become_pass': self.options.become_ask_pass
        }
        # 设置passwords
        self.inventory_file = self.options_dict.get('inventory', '')

        self.loader = DataLoader()
        self._get_vault_pwd()
        self.variable_manager = VariableManager()
        self.variable_manager.extra_vars = load_extra_vars(
            loader=self.loader, options=self.options)
        self.variable_manager.options_vars = load_options_vars(self.options)

        self.inventory = Inventory(loader=self.loader,
                                   variable_manager=self.variable_manager,
                                   host_list=self.inventory_file)
        self.variable_manager.set_inventory(self.inventory)
        self.inventory.subset(self.options.subset)