diff --git a/Dockerfile b/Dockerfile index 7a15e7b..3500f26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,35 +1,11 @@ -FROM centos:7 -# 设置编码 -ENV LANG en_US.UTF-8 -# 同步时间 -ENV TZ=Asia/Shanghai -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone +FROM registry.cn-hangzhou.aliyuncs.com/sourcegarden/python:centos7-3.6 -# 1. 安装基本依赖 -RUN yum update -y && yum install epel-release -y && yum update -y && yum install wget unzip epel-release nginx xz gcc automake zlib-devel openssl-devel supervisor groupinstall development libxslt-devel libxml2-devel libcurl-devel git -y -#WORKDIR /var/www/ - -# 2. 准备python -RUN wget https://www.python.org/ftp/python/3.6.6/Python-3.6.6.tar.xz -RUN xz -d Python-3.6.6.tar.xz && tar xvf Python-3.6.6.tar && cd Python-3.6.6 && ./configure && make && make install - -# 3. 安装websdk -RUN pip3 install --upgrade pip -RUN pip3 install -U git+https://github.com/ss1917/ops_sdk.git - -# 4. 复制代码 -RUN mkdir -p /var/www/ ADD . /var/www/codo-tools/ +RUN pip3 install -r /var/www/codo-tools/requirements.txt -# 5. 安装pip依赖 -RUN pip3 install -r /var/www/codo-tools/doc/requirements.txt - -# 6. 日志 -VOLUME /var/log/ - -# 7. 准备文件 -COPY doc/nginx_ops.conf /etc/nginx/conf.d/default.conf -COPY doc/supervisor_ops.conf /etc/supervisord.conf +COPY docker/nginx_default.conf /etc/nginx/nginx.conf +COPY docker/nginx_ops.conf /etc/nginx/conf.d/codo-tools.conf +COPY docker/supervisor_ops.conf /etc/supervisord.conf EXPOSE 80 CMD ["/usr/bin/supervisord"] \ No newline at end of file diff --git a/biz/crontab_app.py b/biz/crontab_app.py index 8cf7055..071f146 100644 --- a/biz/crontab_app.py +++ b/biz/crontab_app.py @@ -1,22 +1,22 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2019/3/21 19:52 -# @Author : Fred Yangxiaofei -# @File : crontab_app.py -# @Role : Application 放一些定时任务 ,可能会导致阻塞 - - -import tornado -from websdk.application import Application as myApplication -from biz.tail_data import tail_data - -class Application(myApplication): - def __init__(self, **settings): - urls = [] - tailed_callback = tornado.ioloop.PeriodicCallback(tail_data, 3600000) # 1小时循环一次 - tailed_callback.start() - super(Application, self).__init__(urls, **settings) - - -if __name__ == '__main__': - pass +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2019/3/21 19:52 +# @Author : Fred Yangxiaofei +# @File : crontab_app.py +# @Role : Application 放一些定时任务 ,可能会导致阻塞 + + +import tornado +from websdk.application import Application as myApplication +from biz.tail_data import tail_data + +class Application(myApplication): + def __init__(self, **settings): + urls = [] + tailed_callback = tornado.ioloop.PeriodicCallback(tail_data, 3600000) # 1小时循环一次 + tailed_callback.start() + super(Application, self).__init__(urls, **settings) + + +if __name__ == '__main__': + pass diff --git a/biz/get_userinfo.py b/biz/get_userinfo.py index 425205b..efb1b87 100644 --- a/biz/get_userinfo.py +++ b/biz/get_userinfo.py @@ -1,27 +1,27 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2019/3/21 15:10 -# @Author : Fred Yangxiaofei -# @File : get_userinfo.py -# @Role : 获取CODO平台用户详细信息 - - -from libs.redis_connect import redis_conn -from websdk.consts import const - - -def get_user_info(): - """ - 从现有redis里面获取用户信息,如:Email,SMS等 - :return: - """ - # 集合 - data_set = redis_conn.smembers(const.USERS_INFO) - # 集合转list - userdata = list(data_set) - # PS:这里codo后端会把数据主动写redis里面,假数据类型:user_data:['{"nickname:杨红飞", "email": "test@domain.cn", "tel": "10000000001"}','{"nickname:杨红飞02", "email": "test02@domain.cn", "tel": "10000000002"}'] - return userdata - - -if __name__ == '__main__': - get_user_info() +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2019/3/21 15:10 +# @Author : Fred Yangxiaofei +# @File : get_userinfo.py +# @Role : 获取CODO平台用户详细信息 + + +from libs.redis_connect import redis_conn +from websdk.consts import const + + +def get_user_info(): + """ + 从现有redis里面获取用户信息,如:Email,SMS等 + :return: + """ + # 集合 + data_set = redis_conn.smembers(const.USERS_INFO) + # 集合转list + userdata = list(data_set) + # PS:这里codo后端会把数据主动写redis里面,假数据类型:user_data:['{"nickname:杨红飞", "email": "test@domain.cn", "tel": "10000000001"}','{"nickname:杨红飞02", "email": "test02@domain.cn", "tel": "10000000002"}'] + return userdata + + +if __name__ == '__main__': + get_user_info() diff --git a/biz/handlers/event_mg_handler.py b/biz/handlers/event_mg_handler.py index 5175b4c..7248ce2 100644 --- a/biz/handlers/event_mg_handler.py +++ b/biz/handlers/event_mg_handler.py @@ -1,124 +1,124 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2019/3/20 19:19 -# @Author : Fred Yangxiaofei -# @File : event_mg_handler.py -# @Role : 事件记录路由 - - - -import json -import re -import datetime -from libs.database import model_to_dict -from models.event_record import EventRecord -from websdk.db_context import DBContext -from websdk.base_handler import LivenessProbe -from libs.base_handler import BaseHandler - -class EventRecordHandler(BaseHandler): - def get(self, *args, **kwargs): - key = self.get_argument('key', default=None, strip=True) - value = self.get_argument('value', default=None, strip=True) - page_size = self.get_argument('page', default=1, strip=True) - limit = self.get_argument('limit', default=15, strip=True) - limit_start = (int(page_size) - 1) * int(limit) - event_record_list = [] - with DBContext('w') as session: - if key and value: - count = session.query(EventRecord).filter_by(**{key: value}).count() - event_record_data = session.query(EventRecord).filter_by(**{key: value}).order_by( - EventRecord.id).offset(limit_start).limit(int(limit)) - else: - count = session.query(EventRecord).count() - event_record_data = session.query(EventRecord).order_by(EventRecord.id).offset( - limit_start).limit(int(limit)) - - for data in event_record_data: - data_dict = model_to_dict(data) - data_dict['event_start_time'] = str(data_dict['event_start_time']) - data_dict['event_end_time'] = str(data_dict['event_end_time']) - data_dict['create_at'] = str(data_dict['create_at']) - data_dict['update_at'] = str(data_dict['update_at']) - event_record_list.append(data_dict) - return self.write(dict(code=0, msg='获取成功', count=count, data=event_record_list)) - - def post(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - event_name = data.get('event_name') - event_status = data.get('event_status') - event_level = data.get('event_level') - event_processing = data.get('event_processing') - event_start_time = data.get('event_start_time') - event_end_time = data.get('event_end_time') - - event_start_time = datetime.datetime.strptime(event_start_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( - hours=8) - event_end_time = datetime.datetime.strptime(event_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( - hours=8) - - if not event_name or not event_status or not event_level or not event_processing or not event_start_time or not event_end_time: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - with DBContext('w', None, True) as session: - name = session.query(EventRecord).filter(EventRecord.event_name == event_name).first() - if name: - return self.write(dict(code=-2, msg='{}已经存在'.format(event_name))) - - session.add( - EventRecord(event_name=event_name, event_status=event_status, event_level=event_level, - event_processing=event_processing, event_start_time=event_start_time, - event_end_time=event_end_time)) - - self.write(dict(code=0, msg='添加成功')) - - def delete(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - event_id = data.get('id') - if not event_id: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - with DBContext('w', None, True) as session: - session.query(EventRecord).filter(EventRecord.id == event_id).delete(synchronize_session=False) - - self.write(dict(code=0, msg='删除成功')) - - def put(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - event_name = data.get('event_name', None) - event_status = data.get('event_status', None) - event_level = data.get('event_level', None) - event_processing = data.get('event_processing', None) - event_start_time = data.get('event_start_time', None) - event_end_time = data.get('event_end_time', None) - - if not event_name or not event_status or not event_level or not event_processing or not event_start_time or not event_end_time: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - update_info = { - "event_status": event_status, - "event_level": event_level, - "event_processing": event_processing, - "event_start_time": event_start_time, - "event_end_time": event_end_time, - } - - if re.search('000Z', event_start_time): - event_start_time = datetime.datetime.strptime(event_start_time, - "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta(hours=8) - update_info['event_start_time'] = event_start_time - - if re.search('000Z', event_end_time): - event_end_time = datetime.datetime.strptime(event_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( - hours=8) - update_info['event_end_time'] = event_end_time - - with DBContext('w', None, True) as session: - session.query(EventRecord).filter(EventRecord.event_name == event_name).update(update_info) - self.write(dict(code=0, msg='更新成功')) - - -event_urls = [ - (r"/v1/tools/event/", EventRecordHandler), - (r"/are_you_ok/", LivenessProbe), -] +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2019/3/20 19:19 +# @Author : Fred Yangxiaofei +# @File : event_mg_handler.py +# @Role : 事件记录路由 + + + +import json +import re +import datetime +from libs.database import model_to_dict +from models.event_record import EventRecord +from websdk.db_context import DBContext +from websdk.base_handler import LivenessProbe +from libs.base_handler import BaseHandler + +class EventRecordHandler(BaseHandler): + def get(self, *args, **kwargs): + key = self.get_argument('key', default=None, strip=True) + value = self.get_argument('value', default=None, strip=True) + page_size = self.get_argument('page', default=1, strip=True) + limit = self.get_argument('limit', default=15, strip=True) + limit_start = (int(page_size) - 1) * int(limit) + event_record_list = [] + with DBContext('w') as session: + if key and value: + count = session.query(EventRecord).filter_by(**{key: value}).count() + event_record_data = session.query(EventRecord).filter_by(**{key: value}).order_by( + EventRecord.id).offset(limit_start).limit(int(limit)) + else: + count = session.query(EventRecord).count() + event_record_data = session.query(EventRecord).order_by(EventRecord.id).offset( + limit_start).limit(int(limit)) + + for data in event_record_data: + data_dict = model_to_dict(data) + data_dict['event_start_time'] = str(data_dict['event_start_time']) + data_dict['event_end_time'] = str(data_dict['event_end_time']) + data_dict['create_at'] = str(data_dict['create_at']) + data_dict['update_at'] = str(data_dict['update_at']) + event_record_list.append(data_dict) + return self.write(dict(code=0, msg='获取成功', count=count, data=event_record_list)) + + def post(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + event_name = data.get('event_name') + event_status = data.get('event_status') + event_level = data.get('event_level') + event_processing = data.get('event_processing') + event_start_time = data.get('event_start_time') + event_end_time = data.get('event_end_time') + + event_start_time = datetime.datetime.strptime(event_start_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( + hours=8) + event_end_time = datetime.datetime.strptime(event_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( + hours=8) + + if not event_name or not event_status or not event_level or not event_processing or not event_start_time or not event_end_time: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + with DBContext('w', None, True) as session: + name = session.query(EventRecord).filter(EventRecord.event_name == event_name).first() + if name: + return self.write(dict(code=-2, msg='{}已经存在'.format(event_name))) + + session.add( + EventRecord(event_name=event_name, event_status=event_status, event_level=event_level, + event_processing=event_processing, event_start_time=event_start_time, + event_end_time=event_end_time)) + + self.write(dict(code=0, msg='添加成功')) + + def delete(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + event_id = data.get('id') + if not event_id: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + with DBContext('w', None, True) as session: + session.query(EventRecord).filter(EventRecord.id == event_id).delete(synchronize_session=False) + + self.write(dict(code=0, msg='删除成功')) + + def put(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + event_name = data.get('event_name', None) + event_status = data.get('event_status', None) + event_level = data.get('event_level', None) + event_processing = data.get('event_processing', None) + event_start_time = data.get('event_start_time', None) + event_end_time = data.get('event_end_time', None) + + if not event_name or not event_status or not event_level or not event_processing or not event_start_time or not event_end_time: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + update_info = { + "event_status": event_status, + "event_level": event_level, + "event_processing": event_processing, + "event_start_time": event_start_time, + "event_end_time": event_end_time, + } + + if re.search('000Z', event_start_time): + event_start_time = datetime.datetime.strptime(event_start_time, + "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta(hours=8) + update_info['event_start_time'] = event_start_time + + if re.search('000Z', event_end_time): + event_end_time = datetime.datetime.strptime(event_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( + hours=8) + update_info['event_end_time'] = event_end_time + + with DBContext('w', None, True) as session: + session.query(EventRecord).filter(EventRecord.event_name == event_name).update(update_info) + self.write(dict(code=0, msg='更新成功')) + + +event_urls = [ + (r"/v1/tools/event/", EventRecordHandler), + (r"/are_you_ok/", LivenessProbe), +] diff --git a/biz/handlers/fault_mg_handler.py b/biz/handlers/fault_mg_handler.py index 5970628..a02ffec 100644 --- a/biz/handlers/fault_mg_handler.py +++ b/biz/handlers/fault_mg_handler.py @@ -1,228 +1,228 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2019/3/20 13:41 -# @Author : Fred Yangxiaofei -# @File : fault_mg_handler.py -# @Role : 故障管理路由 - - -import json -import re -import datetime -from libs.database import model_to_dict -from models.fault_mg import Fault -from websdk.db_context import DBContext -from websdk.consts import const -from websdk.tools import convert -from biz.promethues_write_redis import redis_conn -from libs.oss import OSSApi -from libs.base_handler import BaseHandler - - -class FaultHandler(BaseHandler): - - def get(self, *args, **kwargs): - key = self.get_argument('key', default=None, strip=True) - value = self.get_argument('value', default=None, strip=True) - page_size = self.get_argument('page', default=1, strip=True) - limit = self.get_argument('limit', default=15, strip=True) - limit_start = (int(page_size) - 1) * int(limit) - fault_list = [] - with DBContext('w') as session: - if key and value: - count = session.query(Fault).filter_by(**{key: value}).count() - - fault_data = session.query(Fault).filter_by(**{key: value}).order_by( - Fault.id).offset(limit_start).limit(int(limit)) - else: - count = session.query(Fault).count() - fault_data = session.query(Fault).order_by(Fault.id).offset( - limit_start).limit(int(limit)) - - for data in fault_data: - data_dict = model_to_dict(data) - data_dict['fault_start_time'] = str(data_dict['fault_start_time']) - data_dict['fault_end_time'] = str(data_dict['fault_end_time']) - data_dict['create_at'] = str(data_dict['create_at']) - data_dict['update_at'] = str(data_dict['update_at']) - fault_list.append(data_dict) - return self.write(dict(code=0, msg='获取成功', count=count, data=fault_list)) - - def post(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - fault_name = data.get('fault_name', None) - fault_level = data.get('fault_level', None) - fault_state = data.get('fault_state', None) - fault_penson = data.get('fault_penson', None) - processing_penson = data.get('processing_penson', None) - fault_report = data.get('fault_report', None) - fault_start_time = data.get('fault_start_time', None) - fault_end_time = data.get('fault_end_time', None) - fault_issue = data.get('fault_issue', None) - fault_summary = data.get('fault_summary', None) - - if not fault_name or not fault_level or not fault_state or not processing_penson or not fault_start_time or not fault_end_time or not fault_issue or not fault_summary: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - fault_start_time = datetime.datetime.strptime(fault_start_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( - hours=8) - fault_end_time = datetime.datetime.strptime(fault_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( - hours=8) - - with DBContext('w', None, True) as session: - name = session.query(Fault).filter(Fault.fault_name == fault_name).first() - if name: - return self.write(dict(code=-2, msg='{}已经存在'.format(fault_name))) - - session.add(Fault(fault_name=fault_name, fault_level=fault_level, fault_state=fault_state, - fault_penson=fault_penson, processing_penson=processing_penson, - fault_report=fault_report, fault_start_time=fault_start_time, - fault_end_time=fault_end_time, fault_issue=fault_issue, fault_summary=fault_summary)) - - self.write(dict(code=0, msg='添加成功')) - - def delete(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - fault_id = data.get('id') - if not fault_id: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - with DBContext('w', None, True) as session: - session.query(Fault).filter(Fault.id == fault_id).delete(synchronize_session=False) - - self.write(dict(code=0, msg='删除成功')) - - def put(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - fault_name = data.get('fault_name', None) - fault_level = data.get('fault_level', None) - fault_state = data.get('fault_state', None) - fault_penson = data.get('fault_penson', None) - processing_penson = data.get('processing_penson', None) - fault_report = data.get('fault_report', None) - fault_start_time = data.get('fault_start_time', None) - fault_end_time = data.get('fault_end_time', None) - fault_issue = data.get('fault_issue', None) - fault_summary = data.get('fault_summary', None) - - if not fault_name or not fault_level or not fault_state or not processing_penson or not fault_start_time or not fault_end_time or not fault_issue or not fault_summary: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - update_info = { - # "fault_name": fault_name, - "fault_level": fault_level, - "fault_state": fault_state, - "fault_penson": fault_penson, - "processing_penson": processing_penson, - "fault_report": fault_report, - "fault_start_time": fault_start_time, - "fault_end_time": fault_end_time, - "fault_issue": fault_issue, - "fault_summary": fault_summary, - } - - if re.search('000Z', fault_start_time): - fault_start_time = datetime.datetime.strptime(fault_start_time, - "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta(hours=8) - update_info['fault_start_time'] = fault_start_time - - if re.search('000Z', fault_end_time): - fault_end_time = datetime.datetime.strptime(fault_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( - hours=8) - update_info['fault_end_time'] = fault_end_time - - with DBContext('w', None, True) as session: - session.query(Fault).filter(Fault.fault_name == fault_name).update(update_info) - # raise HTTPError(403, "%s is not a file", self.path) - self.write(dict(code=0, msg='更新成功')) - - -class UpLoadFileHandler(BaseHandler): - def post(self, *args, **kwargs): - ###文件保存到本地 - # Base_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - # upload_path = '{}/static'.format(Base_DIR) - # file_metas = self.request.files.get('file', None) # 提取表单中‘name’为‘file’的文件元数据 - # ret = {'result': 'OK'} - # if not file_metas: - # ret['result'] = 'Invalid Args' - # return ret - # - # for meta in file_metas: - # filename = meta['filename'] - # print('filename---->', filename) - # file_path = os.path.join(upload_path, filename) - # with open(file_path, 'wb') as up: - # up.write(meta['body']) - # - # self.write(json.dumps(ret)) - - ###文件保存到OSS - ###获取OSS的配置 - cache_config_info = redis_conn.hgetall(const.APP_SETTINGS) - if cache_config_info: - config_info = convert(cache_config_info) - else: - return self.write(dict(code=-1, msg='【系统管理】-【系统配置】-【存储配置】中没有检测到OSS配置信息')) - - file_metas = self.request.files.get('file', None) # 提取表单中‘name’为‘file’的文件元数据 - - if not file_metas: - return self.write(dict(code=-2, msg='没有文件数据')) - - for meta in file_metas: - filename = meta['filename'] - # print('filename---->', filename) - file_data = meta['body'] - oss_data = { - 'STORAGE_KEY_ID': config_info.get('STORAGE_KEY_ID'), - 'STORAGE_KEY_SECRET': config_info.get('STORAGE_KEY_SECRET'), - 'STORAGE_REGION': config_info.get('STORAGE_REGION'), - 'STORAGE_NAME': config_info.get('STORAGE_NAME'), - 'STORAGE_PATH': 'fault' # https://opendevops.oss-cn-shanghai.aliyuncs.com/fault/xxx.pdf - } - # - # obj = OSSApi( - # oss_data.get('STORAGE_KEY_ID'), 'xxxx', - # oss_data.get('STORAGE_REGION'), - # oss_data.get('STORAGE_NAME'), oss_data.get('STORAGE_PATH')) - # obj.setObj(filename, file_data) - try: - obj = OSSApi( - oss_data.get('STORAGE_KEY_ID'), oss_data.get('STORAGE_KEY_SECRET'), - oss_data.get('STORAGE_REGION'), - oss_data.get('STORAGE_NAME'), oss_data.get('STORAGE_PATH')) - obj.setObj(filename, file_data) - except Exception as e: - return self.write(dict(code=-1, msg='上传失败,请检查OSS配置')) - - - self.write(dict(code=0, msg="上传成功")) - -class GetBucketInfoHandler(BaseHandler): - def get(self, *args, **kwargs): - """从redis获取阿里云OSS基本信息""" - cache_config_info = redis_conn.hgetall(const.APP_SETTINGS) - - if cache_config_info: - config_info = convert(cache_config_info) - - if not config_info.get('STORAGE_REGION') and not config_info.get('STORAGE_REGION'): - return self.write(dict(code=-1, msg='没有发现OSS配置信息')) - - oss_info = { - 'STORAGE_REGION': config_info.get('STORAGE_REGION'), - 'STORAGE_NAME': config_info.get('STORAGE_NAME') - } - self.write(dict(code=0, msg="获取成功", data=oss_info)) - else: - self.write(dict(code=-2, msg="没有在redis缓存发现配置信息")) - - - -fault_urls = [ - (r"/v1/tools/fault/", FaultHandler), - (r"/v1/tools/fault/upload/", UpLoadFileHandler), - (r"/v1/tools/fault/oss/", GetBucketInfoHandler), - -] +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2019/3/20 13:41 +# @Author : Fred Yangxiaofei +# @File : fault_mg_handler.py +# @Role : 故障管理路由 + + +import json +import re +import datetime +from libs.database import model_to_dict +from models.fault_mg import Fault +from websdk.db_context import DBContext +from websdk.consts import const +from websdk.tools import convert +from biz.promethues_write_redis import redis_conn +from libs.oss import OSSApi +from libs.base_handler import BaseHandler + + +class FaultHandler(BaseHandler): + + def get(self, *args, **kwargs): + key = self.get_argument('key', default=None, strip=True) + value = self.get_argument('value', default=None, strip=True) + page_size = self.get_argument('page', default=1, strip=True) + limit = self.get_argument('limit', default=15, strip=True) + limit_start = (int(page_size) - 1) * int(limit) + fault_list = [] + with DBContext('w') as session: + if key and value: + count = session.query(Fault).filter_by(**{key: value}).count() + + fault_data = session.query(Fault).filter_by(**{key: value}).order_by( + Fault.id).offset(limit_start).limit(int(limit)) + else: + count = session.query(Fault).count() + fault_data = session.query(Fault).order_by(Fault.id).offset( + limit_start).limit(int(limit)) + + for data in fault_data: + data_dict = model_to_dict(data) + data_dict['fault_start_time'] = str(data_dict['fault_start_time']) + data_dict['fault_end_time'] = str(data_dict['fault_end_time']) + data_dict['create_at'] = str(data_dict['create_at']) + data_dict['update_at'] = str(data_dict['update_at']) + fault_list.append(data_dict) + return self.write(dict(code=0, msg='获取成功', count=count, data=fault_list)) + + def post(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + fault_name = data.get('fault_name', None) + fault_level = data.get('fault_level', None) + fault_state = data.get('fault_state', None) + fault_penson = data.get('fault_penson', None) + processing_penson = data.get('processing_penson', None) + fault_report = data.get('fault_report', None) + fault_start_time = data.get('fault_start_time', None) + fault_end_time = data.get('fault_end_time', None) + fault_issue = data.get('fault_issue', None) + fault_summary = data.get('fault_summary', None) + + if not fault_name or not fault_level or not fault_state or not processing_penson or not fault_start_time or not fault_end_time or not fault_issue or not fault_summary: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + fault_start_time = datetime.datetime.strptime(fault_start_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( + hours=8) + fault_end_time = datetime.datetime.strptime(fault_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( + hours=8) + + with DBContext('w', None, True) as session: + name = session.query(Fault).filter(Fault.fault_name == fault_name).first() + if name: + return self.write(dict(code=-2, msg='{}已经存在'.format(fault_name))) + + session.add(Fault(fault_name=fault_name, fault_level=fault_level, fault_state=fault_state, + fault_penson=fault_penson, processing_penson=processing_penson, + fault_report=fault_report, fault_start_time=fault_start_time, + fault_end_time=fault_end_time, fault_issue=fault_issue, fault_summary=fault_summary)) + + self.write(dict(code=0, msg='添加成功')) + + def delete(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + fault_id = data.get('id') + if not fault_id: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + with DBContext('w', None, True) as session: + session.query(Fault).filter(Fault.id == fault_id).delete(synchronize_session=False) + + self.write(dict(code=0, msg='删除成功')) + + def put(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + fault_name = data.get('fault_name', None) + fault_level = data.get('fault_level', None) + fault_state = data.get('fault_state', None) + fault_penson = data.get('fault_penson', None) + processing_penson = data.get('processing_penson', None) + fault_report = data.get('fault_report', None) + fault_start_time = data.get('fault_start_time', None) + fault_end_time = data.get('fault_end_time', None) + fault_issue = data.get('fault_issue', None) + fault_summary = data.get('fault_summary', None) + + if not fault_name or not fault_level or not fault_state or not processing_penson or not fault_start_time or not fault_end_time or not fault_issue or not fault_summary: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + update_info = { + # "fault_name": fault_name, + "fault_level": fault_level, + "fault_state": fault_state, + "fault_penson": fault_penson, + "processing_penson": processing_penson, + "fault_report": fault_report, + "fault_start_time": fault_start_time, + "fault_end_time": fault_end_time, + "fault_issue": fault_issue, + "fault_summary": fault_summary, + } + + if re.search('000Z', fault_start_time): + fault_start_time = datetime.datetime.strptime(fault_start_time, + "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta(hours=8) + update_info['fault_start_time'] = fault_start_time + + if re.search('000Z', fault_end_time): + fault_end_time = datetime.datetime.strptime(fault_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( + hours=8) + update_info['fault_end_time'] = fault_end_time + + with DBContext('w', None, True) as session: + session.query(Fault).filter(Fault.fault_name == fault_name).update(update_info) + # raise HTTPError(403, "%s is not a file", self.path) + self.write(dict(code=0, msg='更新成功')) + + +class UpLoadFileHandler(BaseHandler): + def post(self, *args, **kwargs): + ###文件保存到本地 + # Base_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + # upload_path = '{}/static'.format(Base_DIR) + # file_metas = self.request.files.get('file', None) # 提取表单中‘name’为‘file’的文件元数据 + # ret = {'result': 'OK'} + # if not file_metas: + # ret['result'] = 'Invalid Args' + # return ret + # + # for meta in file_metas: + # filename = meta['filename'] + # print('filename---->', filename) + # file_path = os.path.join(upload_path, filename) + # with open(file_path, 'wb') as up: + # up.write(meta['body']) + # + # self.write(json.dumps(ret)) + + ###文件保存到OSS + ###获取OSS的配置 + cache_config_info = redis_conn.hgetall(const.APP_SETTINGS) + if cache_config_info: + config_info = convert(cache_config_info) + else: + return self.write(dict(code=-1, msg='【系统管理】-【系统配置】-【存储配置】中没有检测到OSS配置信息')) + + file_metas = self.request.files.get('file', None) # 提取表单中‘name’为‘file’的文件元数据 + + if not file_metas: + return self.write(dict(code=-2, msg='没有文件数据')) + + for meta in file_metas: + filename = meta['filename'] + # print('filename---->', filename) + file_data = meta['body'] + oss_data = { + 'STORAGE_KEY_ID': config_info.get('STORAGE_KEY_ID'), + 'STORAGE_KEY_SECRET': config_info.get('STORAGE_KEY_SECRET'), + 'STORAGE_REGION': config_info.get('STORAGE_REGION'), + 'STORAGE_NAME': config_info.get('STORAGE_NAME'), + 'STORAGE_PATH': 'fault' # https://opendevops.oss-cn-shanghai.aliyuncs.com/fault/xxx.pdf + } + # + # obj = OSSApi( + # oss_data.get('STORAGE_KEY_ID'), 'xxxx', + # oss_data.get('STORAGE_REGION'), + # oss_data.get('STORAGE_NAME'), oss_data.get('STORAGE_PATH')) + # obj.setObj(filename, file_data) + try: + obj = OSSApi( + oss_data.get('STORAGE_KEY_ID'), oss_data.get('STORAGE_KEY_SECRET'), + oss_data.get('STORAGE_REGION'), + oss_data.get('STORAGE_NAME'), oss_data.get('STORAGE_PATH')) + obj.setObj(filename, file_data) + except Exception as e: + return self.write(dict(code=-1, msg='上传失败,请检查OSS配置')) + + + self.write(dict(code=0, msg="上传成功")) + +class GetBucketInfoHandler(BaseHandler): + def get(self, *args, **kwargs): + """从redis获取阿里云OSS基本信息""" + cache_config_info = redis_conn.hgetall(const.APP_SETTINGS) + + if cache_config_info: + config_info = convert(cache_config_info) + + if not config_info.get('STORAGE_REGION') and not config_info.get('STORAGE_REGION'): + return self.write(dict(code=-1, msg='没有发现OSS配置信息')) + + oss_info = { + 'STORAGE_REGION': config_info.get('STORAGE_REGION'), + 'STORAGE_NAME': config_info.get('STORAGE_NAME') + } + self.write(dict(code=0, msg="获取成功", data=oss_info)) + else: + self.write(dict(code=-2, msg="没有在redis缓存发现配置信息")) + + + +fault_urls = [ + (r"/v1/tools/fault/", FaultHandler), + (r"/v1/tools/fault/upload/", UpLoadFileHandler), + (r"/v1/tools/fault/oss/", GetBucketInfoHandler), + +] diff --git a/biz/handlers/mycrypt_handler.py b/biz/handlers/mycrypt_handler.py index efe8d96..7472c51 100644 --- a/biz/handlers/mycrypt_handler.py +++ b/biz/handlers/mycrypt_handler.py @@ -1,49 +1,49 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2019/3/25 14:00 -# @Author : Fred Yangxiaofei -# @File : mycrypt_handler.py -# @Role : 加密解密路由 - - -import tornado.web -from biz.mycrypt import MyCrypt -import binascii -from libs.base_handler import BaseHandler - -class MyCryptHandler(BaseHandler): - - def get(self, *args, **kwargs): - key = self.get_argument('key', default=None, strip=True) - value = self.get_argument('value', default=None, strip=True) - - # text = self.get_argument('text', default=None, strip=True) - # ciphertext = self.get_argument('ciphertext', default=None, strip=True) - - if not key and not value: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - # 实例化 - mc = MyCrypt() - # 用户给正常密码,我们就进行加密操作 - try: - - if key == 'text': - # 加密方法 - ciphertext = mc.my_encrypt(value) - return self.write(dict(code=0, msg="加密成功", data=ciphertext)) - - # 用户给加密文本,我们就进行解密操作 - if key == 'ciphertext': - # 解密方法 - text = mc.my_decrypt(value) - return self.write(dict(code=0, msg="解密成功", data=text)) - except binascii.Error: - return self.write(dict(code=-3, msg="解密格式错误")) - - - - -mycrypt_urls = [ - (r"/v1/tools/mycrypt/", MyCryptHandler) -] +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2019/3/25 14:00 +# @Author : Fred Yangxiaofei +# @File : mycrypt_handler.py +# @Role : 加密解密路由 + + +import tornado.web +from biz.mycrypt import MyCrypt +import binascii +from libs.base_handler import BaseHandler + +class MyCryptHandler(BaseHandler): + + def get(self, *args, **kwargs): + key = self.get_argument('key', default=None, strip=True) + value = self.get_argument('value', default=None, strip=True) + + # text = self.get_argument('text', default=None, strip=True) + # ciphertext = self.get_argument('ciphertext', default=None, strip=True) + + if not key and not value: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + # 实例化 + mc = MyCrypt() + # 用户给正常密码,我们就进行加密操作 + try: + + if key == 'text': + # 加密方法 + ciphertext = mc.my_encrypt(value) + return self.write(dict(code=0, msg="加密成功", data=ciphertext)) + + # 用户给加密文本,我们就进行解密操作 + if key == 'ciphertext': + # 解密方法 + text = mc.my_decrypt(value) + return self.write(dict(code=0, msg="解密成功", data=text)) + except binascii.Error: + return self.write(dict(code=-3, msg="解密格式错误")) + + + + +mycrypt_urls = [ + (r"/v1/tools/mycrypt/", MyCryptHandler) +] diff --git a/biz/handlers/paid_mg_handler.py b/biz/handlers/paid_mg_handler.py index fecf819..baa10cc 100644 --- a/biz/handlers/paid_mg_handler.py +++ b/biz/handlers/paid_mg_handler.py @@ -1,126 +1,126 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2019/3/21 11:13 -# @Author : Fred Yangxiaofei -# @File : paid_mg_handler.py -# @Role : 付费管理路由 - - -import json -import re -import datetime -from libs.database import model_to_dict -from models.paid_mg import PaidMG -from websdk.db_context import DBContext -from libs.base_handler import BaseHandler - - -class PaidMGHandler(BaseHandler): - def get(self, *args, **kwargs): - key = self.get_argument('key', default=None, strip=True) - value = self.get_argument('value', default=None, strip=True) - page_size = self.get_argument('page', default=1, strip=True) - limit = self.get_argument('limit', default=15, strip=True) - limit_start = (int(page_size) - 1) * int(limit) - paid_list = [] - with DBContext('w') as session: - if key and value: - count = session.query(PaidMG).filter_by(**{key: value}).count() - paid_data = session.query(PaidMG).filter_by(**{key: value}).order_by( - PaidMG.id).offset(limit_start).limit(int(limit)) - else: - count = session.query(PaidMG).count() - paid_data = session.query(PaidMG).order_by(PaidMG.id).offset( - limit_start).limit(int(limit)) - - for data in paid_data: - data_dict = model_to_dict(data) - data_dict['paid_start_time'] = str(data_dict['paid_start_time']) - data_dict['paid_end_time'] = str(data_dict['paid_end_time']) - data_dict['create_at'] = str(data_dict['create_at']) - data_dict['update_at'] = str(data_dict['update_at']) - if data_dict['nicknames']: - data_dict['nicknames'] = data_dict['nicknames'].split(',') - paid_list.append(data_dict) - return self.write(dict(code=0, msg='获取成功', count=count, data=paid_list)) - - def post(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - paid_name = data.get('paid_name', None) - paid_start_time = data.get('paid_start_time', None) - paid_end_time = data.get('paid_end_time', None) - reminder_day = data.get('reminder_day', None) - nicknames = data.get('nicknames', '') - - if not paid_name or not paid_start_time or not paid_end_time or not reminder_day or not nicknames: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - if nicknames: - nicknames = ','.join(nicknames) - - paid_start_time = datetime.datetime.strptime(paid_start_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( - hours=8) - paid_end_time = datetime.datetime.strptime(paid_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( - hours=8) - - with DBContext('w', None, True) as session: - name = session.query(PaidMG).filter(PaidMG.paid_name == paid_name).first() - if name: - return self.write(dict(code=-2, msg='{}已经存在'.format(paid_name))) - session.add( - PaidMG(paid_name=paid_name, paid_start_time=paid_start_time, paid_end_time=paid_end_time, - reminder_day=reminder_day, nicknames=nicknames)) - - self.write(dict(code=0, msg='添加成功')) - - def delete(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - paid_id = data.get('id') - if not paid_id: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - with DBContext('w', None, True) as session: - session.query(PaidMG).filter(PaidMG.id == paid_id).delete(synchronize_session=False) - - self.write(dict(code=0, msg='删除成功')) - - def put(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - paid_id = data.get('id') - paid_name = data.get('paid_name', None) - paid_start_time = data.get('paid_start_time', None) - paid_end_time = data.get('paid_end_time', None) - reminder_day = data.get('reminder_day', None) - nicknames = data.get('nicknames', None) - - if not paid_name or not paid_start_time or not paid_end_time or not reminder_day or not nicknames: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - if nicknames: - nicknames = ','.join(nicknames) - - update_info = { - "paid_start_time": paid_start_time, - "paid_end_time": paid_end_time, - "reminder_day": reminder_day, - "nicknames": nicknames - } - - if re.search('000Z', paid_start_time): - paid_start_time = datetime.datetime.strptime(paid_start_time, - "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta(hours=8) - update_info['paid_start_time'] = paid_start_time - - if re.search('000Z', paid_end_time): - paid_end_time = datetime.datetime.strptime(paid_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( - hours=8) - update_info['paid_end_time'] = paid_end_time - - with DBContext('w', None, True) as session: - session.query(PaidMG).filter(PaidMG.paid_name == paid_name).update(update_info) - self.write(dict(code=0, msg='更新成功')) - - -paid_urls = [ - (r"/v1/tools/paid/", PaidMGHandler) -] +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2019/3/21 11:13 +# @Author : Fred Yangxiaofei +# @File : paid_mg_handler.py +# @Role : 付费管理路由 + + +import json +import re +import datetime +from libs.database import model_to_dict +from models.paid_mg import PaidMG +from websdk.db_context import DBContext +from libs.base_handler import BaseHandler + + +class PaidMGHandler(BaseHandler): + def get(self, *args, **kwargs): + key = self.get_argument('key', default=None, strip=True) + value = self.get_argument('value', default=None, strip=True) + page_size = self.get_argument('page', default=1, strip=True) + limit = self.get_argument('limit', default=15, strip=True) + limit_start = (int(page_size) - 1) * int(limit) + paid_list = [] + with DBContext('w') as session: + if key and value: + count = session.query(PaidMG).filter_by(**{key: value}).count() + paid_data = session.query(PaidMG).filter_by(**{key: value}).order_by( + PaidMG.id).offset(limit_start).limit(int(limit)) + else: + count = session.query(PaidMG).count() + paid_data = session.query(PaidMG).order_by(PaidMG.id).offset( + limit_start).limit(int(limit)) + + for data in paid_data: + data_dict = model_to_dict(data) + data_dict['paid_start_time'] = str(data_dict['paid_start_time']) + data_dict['paid_end_time'] = str(data_dict['paid_end_time']) + data_dict['create_at'] = str(data_dict['create_at']) + data_dict['update_at'] = str(data_dict['update_at']) + if data_dict['nicknames']: + data_dict['nicknames'] = data_dict['nicknames'].split(',') + paid_list.append(data_dict) + return self.write(dict(code=0, msg='获取成功', count=count, data=paid_list)) + + def post(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + paid_name = data.get('paid_name', None) + paid_start_time = data.get('paid_start_time', None) + paid_end_time = data.get('paid_end_time', None) + reminder_day = data.get('reminder_day', None) + nicknames = data.get('nicknames', '') + + if not paid_name or not paid_start_time or not paid_end_time or not reminder_day or not nicknames: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + if nicknames: + nicknames = ','.join(nicknames) + + paid_start_time = datetime.datetime.strptime(paid_start_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( + hours=8) + paid_end_time = datetime.datetime.strptime(paid_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( + hours=8) + + with DBContext('w', None, True) as session: + name = session.query(PaidMG).filter(PaidMG.paid_name == paid_name).first() + if name: + return self.write(dict(code=-2, msg='{}已经存在'.format(paid_name))) + session.add( + PaidMG(paid_name=paid_name, paid_start_time=paid_start_time, paid_end_time=paid_end_time, + reminder_day=reminder_day, nicknames=nicknames)) + + self.write(dict(code=0, msg='添加成功')) + + def delete(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + paid_id = data.get('id') + if not paid_id: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + with DBContext('w', None, True) as session: + session.query(PaidMG).filter(PaidMG.id == paid_id).delete(synchronize_session=False) + + self.write(dict(code=0, msg='删除成功')) + + def put(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + paid_id = data.get('id') + paid_name = data.get('paid_name', None) + paid_start_time = data.get('paid_start_time', None) + paid_end_time = data.get('paid_end_time', None) + reminder_day = data.get('reminder_day', None) + nicknames = data.get('nicknames', None) + + if not paid_name or not paid_start_time or not paid_end_time or not reminder_day or not nicknames: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + if nicknames: + nicknames = ','.join(nicknames) + + update_info = { + "paid_start_time": paid_start_time, + "paid_end_time": paid_end_time, + "reminder_day": reminder_day, + "nicknames": nicknames + } + + if re.search('000Z', paid_start_time): + paid_start_time = datetime.datetime.strptime(paid_start_time, + "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta(hours=8) + update_info['paid_start_time'] = paid_start_time + + if re.search('000Z', paid_end_time): + paid_end_time = datetime.datetime.strptime(paid_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( + hours=8) + update_info['paid_end_time'] = paid_end_time + + with DBContext('w', None, True) as session: + session.query(PaidMG).filter(PaidMG.paid_name == paid_name).update(update_info) + self.write(dict(code=0, msg='更新成功')) + + +paid_urls = [ + (r"/v1/tools/paid/", PaidMGHandler) +] diff --git a/biz/handlers/password_handler.py b/biz/handlers/password_handler.py index f3792fc..f624b3c 100644 --- a/biz/handlers/password_handler.py +++ b/biz/handlers/password_handler.py @@ -1,32 +1,32 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2019/3/22 13:24 -# @Author : Fred Yangxiaofei -# @File : password_handler.py -# @Role : 随机密码生成路由 - - - -import string -import random -from libs.base_handler import BaseHandler - - -class PasswordHandler(BaseHandler): - def get(self, *args, **kwargs): - num = self.get_argument('num', default=None, strip=True) - if not num: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - # if not isinstance(num, int): - # return self.write(dict(code=-3, msg='参数必须是int类型')) - - chars = string.ascii_letters + string.digits - random_password = ''.join([random.choice(chars) for i in range(int(num))]) - - return self.write(dict(code=0, msg='获取成功', data=random_password)) - - -password_urls = [ - (r"/v1/tools/password/", PasswordHandler) -] +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2019/3/22 13:24 +# @Author : Fred Yangxiaofei +# @File : password_handler.py +# @Role : 随机密码生成路由 + + + +import string +import random +from libs.base_handler import BaseHandler + + +class PasswordHandler(BaseHandler): + def get(self, *args, **kwargs): + num = self.get_argument('num', default=None, strip=True) + if not num: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + # if not isinstance(num, int): + # return self.write(dict(code=-3, msg='参数必须是int类型')) + + chars = string.ascii_letters + string.digits + random_password = ''.join([random.choice(chars) for i in range(int(num))]) + + return self.write(dict(code=0, msg='获取成功', data=random_password)) + + +password_urls = [ + (r"/v1/tools/password/", PasswordHandler) +] diff --git a/biz/handlers/project_mg_handler.py b/biz/handlers/project_mg_handler.py index a7cb209..8487ff0 100644 --- a/biz/handlers/project_mg_handler.py +++ b/biz/handlers/project_mg_handler.py @@ -1,122 +1,122 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2019/3/20 17:36 -# @Author : Fred Yangxiaofei -# @File : project_mg_handler.py -# @Role : 项目管理信息路由 - - -import json -import re -import datetime -from libs.database import model_to_dict -from models.project_mg import ProjectMG -from websdk.db_context import DBContext -from libs.base_handler import BaseHandler - - -class ProjectMGHandler(BaseHandler): - def get(self, *args, **kwargs): - key = self.get_argument('key', default=None, strip=True) - value = self.get_argument('value', default=None, strip=True) - page_size = self.get_argument('page', default=1, strip=True) - limit = self.get_argument('limit', default=15, strip=True) - limit_start = (int(page_size) - 1) * int(limit) - project_list = [] - with DBContext('w') as session: - if key and value: - count = session.query(ProjectMG).filter_by(**{key: value}).count() - project_data = session.query(ProjectMG).filter_by(**{key: value}).order_by( - ProjectMG.id).offset(limit_start).limit(int(limit)) - else: - count = session.query(ProjectMG).count() - project_data = session.query(ProjectMG).order_by(ProjectMG.id).offset( - limit_start).limit(int(limit)) - - for data in project_data: - data_dict = model_to_dict(data) - data_dict['project_start_time'] = str(data_dict['project_start_time']) - data_dict['project_end_time'] = str(data_dict['project_end_time']) - data_dict['create_at'] = str(data_dict['create_at']) - data_dict['update_at'] = str(data_dict['update_at']) - project_list.append(data_dict) - return self.write(dict(code=0, msg='获取成功', count=count, data=project_list)) - - def post(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - project_name = data.get('project_name', None) - project_status = data.get('project_status', None) - project_requester = data.get('project_requester', None) - project_processing = data.get('project_processing', None) - project_start_time = data.get('project_start_time', None) - project_end_time = data.get('project_end_time', None) - - if not project_name or not project_status or not project_requester or not project_processing or not project_start_time or not project_end_time: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - project_start_time = datetime.datetime.strptime(project_start_time, - "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta(hours=8) - project_end_time = datetime.datetime.strptime(project_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( - hours=8) - - with DBContext('w', None, True) as session: - name = session.query(ProjectMG).filter(ProjectMG.project_name == project_name).first() - if name: - return self.write(dict(code=-2, msg='{}已经存在'.format(project_name))) - session.add( - ProjectMG(project_name=project_name, project_status=project_status, project_requester=project_requester, - project_processing=project_processing, project_start_time=project_start_time, - project_end_time=project_end_time)) - - self.write(dict(code=0, msg='添加成功')) - - def delete(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - project_id = data.get('id') - if not project_id: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - with DBContext('w', None, True) as session: - session.query(ProjectMG).filter(ProjectMG.id == project_id).delete(synchronize_session=False) - - self.write(dict(code=0, msg='删除成功')) - - def put(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - project_name = data.get('project_name', None) - project_status = data.get('project_status', None) - project_requester = data.get('project_requester', None) - project_processing = data.get('project_processing', None) - project_start_time = data.get('project_start_time', None) - project_end_time = data.get('project_end_time', None) - - if not project_name or not project_status or not project_requester or not project_processing or not project_start_time or not project_end_time: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - update_info = { - "project_status": project_status, - "project_requester": project_requester, - "project_processing": project_processing, - "project_start_time": project_start_time, - "project_end_time": project_end_time, - } - - if re.search('000Z', project_start_time): - project_start_time = datetime.datetime.strptime(project_start_time, - "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta(hours=8) - update_info['project_start_time'] = project_start_time - - if re.search('000Z', project_end_time): - project_end_time = datetime.datetime.strptime(project_end_time, - "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( - hours=8) - update_info['project_end_time'] = project_end_time - - with DBContext('w', None, True) as session: - session.query(ProjectMG).filter(ProjectMG.project_name == project_name).update(update_info) - self.write(dict(code=0, msg='更新成功')) - - -project_urls = [ - (r"/v1/tools/project/", ProjectMGHandler), -] +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2019/3/20 17:36 +# @Author : Fred Yangxiaofei +# @File : project_mg_handler.py +# @Role : 项目管理信息路由 + + +import json +import re +import datetime +from libs.database import model_to_dict +from models.project_mg import ProjectMG +from websdk.db_context import DBContext +from libs.base_handler import BaseHandler + + +class ProjectMGHandler(BaseHandler): + def get(self, *args, **kwargs): + key = self.get_argument('key', default=None, strip=True) + value = self.get_argument('value', default=None, strip=True) + page_size = self.get_argument('page', default=1, strip=True) + limit = self.get_argument('limit', default=15, strip=True) + limit_start = (int(page_size) - 1) * int(limit) + project_list = [] + with DBContext('w') as session: + if key and value: + count = session.query(ProjectMG).filter_by(**{key: value}).count() + project_data = session.query(ProjectMG).filter_by(**{key: value}).order_by( + ProjectMG.id).offset(limit_start).limit(int(limit)) + else: + count = session.query(ProjectMG).count() + project_data = session.query(ProjectMG).order_by(ProjectMG.id).offset( + limit_start).limit(int(limit)) + + for data in project_data: + data_dict = model_to_dict(data) + data_dict['project_start_time'] = str(data_dict['project_start_time']) + data_dict['project_end_time'] = str(data_dict['project_end_time']) + data_dict['create_at'] = str(data_dict['create_at']) + data_dict['update_at'] = str(data_dict['update_at']) + project_list.append(data_dict) + return self.write(dict(code=0, msg='获取成功', count=count, data=project_list)) + + def post(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + project_name = data.get('project_name', None) + project_status = data.get('project_status', None) + project_requester = data.get('project_requester', None) + project_processing = data.get('project_processing', None) + project_start_time = data.get('project_start_time', None) + project_end_time = data.get('project_end_time', None) + + if not project_name or not project_status or not project_requester or not project_processing or not project_start_time or not project_end_time: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + project_start_time = datetime.datetime.strptime(project_start_time, + "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta(hours=8) + project_end_time = datetime.datetime.strptime(project_end_time, "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( + hours=8) + + with DBContext('w', None, True) as session: + name = session.query(ProjectMG).filter(ProjectMG.project_name == project_name).first() + if name: + return self.write(dict(code=-2, msg='{}已经存在'.format(project_name))) + session.add( + ProjectMG(project_name=project_name, project_status=project_status, project_requester=project_requester, + project_processing=project_processing, project_start_time=project_start_time, + project_end_time=project_end_time)) + + self.write(dict(code=0, msg='添加成功')) + + def delete(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + project_id = data.get('id') + if not project_id: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + with DBContext('w', None, True) as session: + session.query(ProjectMG).filter(ProjectMG.id == project_id).delete(synchronize_session=False) + + self.write(dict(code=0, msg='删除成功')) + + def put(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + project_name = data.get('project_name', None) + project_status = data.get('project_status', None) + project_requester = data.get('project_requester', None) + project_processing = data.get('project_processing', None) + project_start_time = data.get('project_start_time', None) + project_end_time = data.get('project_end_time', None) + + if not project_name or not project_status or not project_requester or not project_processing or not project_start_time or not project_end_time: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + update_info = { + "project_status": project_status, + "project_requester": project_requester, + "project_processing": project_processing, + "project_start_time": project_start_time, + "project_end_time": project_end_time, + } + + if re.search('000Z', project_start_time): + project_start_time = datetime.datetime.strptime(project_start_time, + "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta(hours=8) + update_info['project_start_time'] = project_start_time + + if re.search('000Z', project_end_time): + project_end_time = datetime.datetime.strptime(project_end_time, + "%Y-%m-%dT%H:%M:%S.%fZ") + datetime.timedelta( + hours=8) + update_info['project_end_time'] = project_end_time + + with DBContext('w', None, True) as session: + session.query(ProjectMG).filter(ProjectMG.project_name == project_name).update(update_info) + self.write(dict(code=0, msg='更新成功')) + + +project_urls = [ + (r"/v1/tools/project/", ProjectMGHandler), +] diff --git a/biz/handlers/zabbix_mg_handler.py b/biz/handlers/zabbix_mg_handler.py index 421b3a3..d1ee0f1 100644 --- a/biz/handlers/zabbix_mg_handler.py +++ b/biz/handlers/zabbix_mg_handler.py @@ -1,549 +1,549 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2019/7/4 15:55 -# @Author : Fred Yangxiaofei -# @File : zabbix_mg_handler.py -# @Role : ZABBIX相关路由 - - -import json -import datetime -from tornado import gen -from tornado import httpclient -from concurrent.futures import ThreadPoolExecutor -from tornado.concurrent import run_on_executor -from libs.database import model_to_dict -from libs.zabbix.login import zabbix_login -from libs.zabbix.get_issues import main as zabbix_last_issues -from models.zabbix_mg import ZabbixConfig, ZabbixSubmitTaskConf, ZabbixHosts, ZabbixHookLog -from websdk.db_context import DBContext -from libs.base_handler import BaseHandler -import tornado.web -from sqlalchemy import or_ -from websdk.web_logs import ins_log -from libs.zabbix.get_hosts import main as get_zabbix_hosts - - -class ZabbixTreeHandler(tornado.web.RequestHandler): - def get(self, *args, **kwargs): - hosts_list = [] - with DBContext('w') as session: - hosts_info = session.query(ZabbixHosts).all() - - for msg in hosts_info: - data_dict = model_to_dict(msg) - hosts_list.append(data_dict) - - _tree = [{"expand": True, "title": "ZABBIX", "children": [], "data_type": 'root'}] - - if hosts_list: - tmp_tree = { - "zabbix_url": {}, - "group_name": {}, - } - - for t in hosts_list: - zabbix_url, group_name = t["zabbix_url"], t['group_name'] - - # 因为是第一层所以没有parent - tmp_tree["zabbix_url"][zabbix_url] = { - "expand": True, "title": zabbix_url, "parent": "ZABBIX", "children": [], "data_type": 'zabbix_url' - } - - tmp_tree["group_name"][zabbix_url + "|" + group_name] = { - "expand": False, "title": group_name, "parent": zabbix_url, "zabbix_url": zabbix_url, - "children": [], "data_type": 'group_name' - } - - for tmp_group in tmp_tree["group_name"].values(): - tmp_tree["zabbix_url"][tmp_group["parent"]]["children"].append(tmp_group) - - for tmp_zabbix in tmp_tree["zabbix_url"].values(): - _tree[0]["children"].append(tmp_zabbix) - - return self.write(dict(code=0, msg='获取项目Tree成功', data=_tree)) - else: - return self.write(dict(code=0, msg='获取项目Tree失败', data=_tree)) - - -class ZabbixHostsHandler(tornado.web.RequestHandler): - def get(self, *args, **kwargs): - zabbix_url = self.get_argument('zabbix_url', default=None, strip=True) - group_name = self.get_argument('group_name', default=None, strip=True) - search_val = self.get_argument('search_val', default=None, strip=True) - host_list = [] - if search_val: - with DBContext('w') as session: - zabbix_host_info = session.query(ZabbixHosts).filter( - or_(ZabbixHosts.group_name.like('%{}%'.format(search_val)), - ZabbixHosts.host_name.like('%{}%'.format(search_val)), - ZabbixHosts.zabbix_url.like('%{}%'.format(search_val))) - ).order_by(ZabbixHosts.zabbix_url, ZabbixHosts.group_name).all() - - elif zabbix_url and group_name: - with DBContext('w') as session: - zabbix_host_info = session.query(ZabbixHosts).filter(ZabbixHosts.zabbix_url == zabbix_url, - ZabbixHosts.group_name == group_name).order_by( - ZabbixHosts.zabbix_url, ZabbixHosts.group_name).all() - else: - with DBContext('w') as session: - zabbix_host_info = session.query(ZabbixHosts).order_by(ZabbixHosts.zabbix_url, - ZabbixHosts.group_name).all() - - for msg in zabbix_host_info: - data_dict = model_to_dict(msg) - hook_list = [] - if data_dict['zabbix_hooks']: - git_hooks = json.loads(data_dict['zabbix_hooks']) - for k, v in git_hooks.items(): - v['alert_title'] = k - hook_list.append(v) - data_dict['hook_list'] = hook_list - host_list.append(data_dict) - - return self.write(dict(code=0, msg='获取成功', data=host_list)) - - def put(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - print('data--->',data) - alert_title = data.get('alert_title').strip() - temp_id = data.get('temp_id') - schedule = data.get('schedule', 'new') - hook_args = data.get('hook_args') - the_id = data.get('the_id') - exec_host = data.get('exec_host', '127.0.0.1') - if not alert_title or not temp_id or not the_id or not exec_host: - return self.write(dict(code=1, msg='关键参数不能为空')) - - if hook_args: - try: - hook_args_dict = json.loads(hook_args) - except Exception as e: - return self.write(dict(code=2, msg='参数字典格式不正确')) - else: - hook_args_dict = dict() - - with DBContext('w', None, True) as session: - zabbix_hooks_info = session.query(ZabbixHosts.zabbix_hooks).filter(ZabbixHosts.id == the_id).first() - hook_dict = zabbix_hooks_info[0] if zabbix_hooks_info else {} - if hook_dict: - try: - hook_dict = json.loads(hook_dict) - except Exception as e: - return self.write(dict(code=2, msg='钩子参数转化为字典的时候出错,请仔细检查相关内容' + str(e))) - - if not hook_dict: - hook_dict = {alert_title: dict(exec_host=exec_host,temp_id=temp_id, schedule=schedule, hook_args=hook_args_dict)} - else: - hook_dict[alert_title] = dict(exec_host=exec_host,temp_id=temp_id, schedule=schedule, hook_args=hook_args_dict) - - hook_dict = json.dumps(hook_dict) - - session.query(ZabbixHosts.zabbix_hooks).filter(ZabbixHosts.id == the_id).update( - {ZabbixHosts.zabbix_hooks: hook_dict}) - - self.write(dict(code=0, msg='更新钩子成功')) - - -class ZabbixConfigHandler(BaseHandler): - - def get(self, *args, **kwargs): - key = self.get_argument('key', default=None, strip=True) - value = self.get_argument('value', default=None, strip=True) - page_size = self.get_argument('page', default=1, strip=True) - limit = self.get_argument('limit', default=15, strip=True) - limit_start = (int(page_size) - 1) * int(limit) - zabbix_list = [] - with DBContext('w') as session: - if key and value: - count = session.query(ZabbixConfig).filter_by(**{key: value}).count() - zabbix_data = session.query(ZabbixConfig).filter_by(**{key: value}).order_by( - ZabbixConfig.id).offset(limit_start).limit(int(limit)) - else: - count = session.query(ZabbixConfig).count() - zabbix_data = session.query(ZabbixConfig).order_by(ZabbixConfig.id).offset( - limit_start).limit(int(limit)) - - for data in zabbix_data: - data_dict = model_to_dict(data) - zabbix_list.append(data_dict) - return self.write(dict(code=0, msg='获取成功', count=count, data=zabbix_list)) - - '''测试用户填写的信息及认证是否正确,防止主进程卡死,使用异步方法测试''' - _thread_pool = ThreadPoolExecutor(1) - - @run_on_executor(executor='_thread_pool') - def login_auth(self, zabbix_url, zabbix_username, zabbix_password): - """ - 测试ZABBIX验证是否可以通过 - :return: - """ - # 错误信息 - err_msg = '' - - ins_log.read_log('info', 'ZABBIX Login Auth') - - try: - zabbix_login(zabbix_url, zabbix_username, zabbix_password) - - except Exception as e: - err_msg = '测试失败,错误信息:{}'.format(e) - - return err_msg - - @gen.coroutine - def post(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - zabbix_name = data.get('zabbix_name', None) - zabbix_url = data.get('zabbix_url', None) - zabbix_username = data.get('zabbix_username', None) - zabbix_password = data.get('zabbix_password', None) - - if not zabbix_url or not zabbix_username or not zabbix_password: - return self.write(dict(code=-2, msg="测试必须要包含:地址、用户、密码信息")) - - msg = yield self.login_auth(zabbix_url, zabbix_username, zabbix_password) - if msg: - # 失败 - return self.write(dict(code=-1, msg=msg)) - - if not zabbix_name or not zabbix_url or not zabbix_username or not zabbix_password: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - with DBContext('w', None, True) as session: - exist_zabbix_name = session.query(ZabbixConfig).filter(ZabbixConfig.zabbix_name == zabbix_name).first() - exist_zabbix_url = session.query(ZabbixConfig).filter(ZabbixConfig.zabbix_url == zabbix_url).first() - - if exist_zabbix_name or exist_zabbix_url: - - update_info = { - "zabbix_name": zabbix_name, - "zabbix_url": zabbix_url, - "zabbix_username": zabbix_username, - "zabbix_password": zabbix_password, - } - - # 测试下编辑完后的信息是否正确 - msg = yield self.login_auth(zabbix_url, zabbix_username, zabbix_password) - if msg: - # 失败 - return self.write(dict(code=-1, msg=msg)) - - with DBContext('w', None, True) as session: - session.query(ZabbixConfig).filter(ZabbixConfig.zabbix_url == zabbix_url).update(update_info) - - return self.write(dict(code=0, msg='更新成功')) - # return self.write(dict(code=-2, msg='name或zabbix url配置信息已经存在')) - session.add( - ZabbixConfig(zabbix_name=zabbix_name, zabbix_url=zabbix_url, zabbix_username=zabbix_username, - zabbix_password=zabbix_password)) - - self.write(dict(code=0, msg='添加成功')) - - def delete(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - zabbix_config_id = data.get('id') - zabbix_url = data.get('zabbix_url') - - if not zabbix_config_id: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - with DBContext('w', None, True) as session: - session.query(ZabbixConfig).filter(ZabbixConfig.id == zabbix_config_id).delete(synchronize_session=False) - session.query(ZabbixHosts).filter(ZabbixHosts.zabbix_url == zabbix_url).delete(synchronize_session=False) - - self.write(dict(code=0, msg='删除成功')) - - -class ZabbixSyncHandler(tornado.web.RequestHandler): - '''刷新ZABBIX地址,将用户所有配置的ZABBIX信息数据都写入数据库''' - - def post(self, *args, **kwargs): - with DBContext('w', None, True) as session: - zabbix_generator_list = get_zabbix_hosts() - if zabbix_generator_list: - for zabbix_gen in zabbix_generator_list: - for host_info in zabbix_gen: - host_name = host_info.get('host_name') - exist_hostname = session.query(ZabbixHosts).filter(ZabbixHosts.host_name == host_name).first() - if not exist_hostname: - session.add( - ZabbixHosts(zabbix_url=host_info.get('zabbix_url'), group_id=host_info.get('group_id'), - group_name=host_info.get('group_name'), - host_id=host_info.get('host_id'), host_name=host_name)) - else: - session.query(ZabbixHosts).filter(ZabbixHosts.host_name == host_name).update(host_info) - session.commit() - - self.write(dict(code=0, msg='刷新成功')) - - -class ZabbixLastIssuesHandler(tornado.web.RequestHandler): - '''获取多ZABBIX ISSUES信息,前端展示出来''' - - def get(self, *args, **kwargs): - last_issues = zabbix_last_issues() - return self.write(dict(code=0, msg='获取成功', data=last_issues)) - - -class ZabbixhookLogsHandler(tornado.web.RequestHandler): - '''获取webhook告警日志''' - - @gen.coroutine - def get(self, *args, **kwargs): - log_list = [] - - with DBContext('w') as session: - hooks_log_info = session.query(ZabbixHookLog).order_by(-ZabbixHookLog.id).limit(200).all() - - for msg in hooks_log_info: - data_dict = model_to_dict(msg) - data_dict['create_time'] = str(data_dict['create_time']) - log_list.append(data_dict) - - return self.write(dict(code=0, msg='获取成功', data=log_list)) - - -class ZabbixSubmitTaskConfHandler(tornado.web.RequestHandler): - '''ZABBIX钩子向任务平台提交任务,需要一个认证''' - - def get(self, *args, **kwargs): - page_size = self.get_argument('page', default=1, strip=True) - limit = self.get_argument('limit', default=1, strip=True) - limit_start = (int(page_size) - 1) * int(limit) # 只能有一条 - submit_task_conf_list = [] - with DBContext('w') as session: - zabbix_submit_task_conf_data = session.query(ZabbixSubmitTaskConf).order_by(ZabbixSubmitTaskConf.id).offset( - limit_start).limit(int(limit)) - for data in zabbix_submit_task_conf_data: - data_dict = model_to_dict(data) - submit_task_conf_list.append(data_dict) - return self.write(dict(code=0, msg='获取成功', data=submit_task_conf_list)) - - async def post(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - task_url = data.get('task_url', None) - auth_key = data.get('auth_key', None) - - if not task_url or not auth_key: - return self.write(dict(code=-2, msg="测试必须要包含:task_url、auth_key信息")) - - # 测试下权限 - http_client = httpclient.AsyncHTTPClient() - cookie = {"Cookie": 'auth_key={}'.format(auth_key)} - response = await http_client.fetch(task_url, method="GET", raise_error=False, headers=cookie) - - if response.code != 200: - return self.write(dict(code=-3, msg="错误码:{}".format(response.code))) - - response_data = json.loads(response.body.decode('utf-8')) - if response_data.get('code') != 0: - return self.write(dict(code=-3, msg="权限错误:{}".format(response_data.get('msg')))) - - # - with DBContext('w', None, True) as session: - exist_config = session.query(ZabbixSubmitTaskConf.id).first() - if not exist_config: - session.add(ZabbixSubmitTaskConf(task_url=task_url, auth_key=auth_key)) - else: - return self.write(dict(code=-4, msg="提交任务的认证配置信息只能存在一条")) - - self.write(dict(code=0, msg='添加成功')) - - def delete(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - submit_task_config_id = data.get('id') - - if not submit_task_config_id: - return self.write(dict(code=-2, msg='关键参数不能为空')) - - with DBContext('w', None, True) as session: - session.query(ZabbixSubmitTaskConf).filter(ZabbixSubmitTaskConf.id == submit_task_config_id).delete( - synchronize_session=False) - self.write(dict(code=0, msg='删除成功')) - - -class ZabbixHookHandler(BaseHandler): - @gen.coroutine - def get(self, *args, **kwargs): - self.write(dict(code=0, msg='获取csrf_key成功', csrf_key=self.new_csrf_key)) - - async def post(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - - print('data----->',data) - ins_log.read_log('info', '接收到数据:{}'.format(data)) - zabbix_url = data.get('zabbix_url') - messages = data.get('messages') - example_messages = 'Zabbix server___127.0.0.1___Zabbix agent on Zabbix server is unreachable for 5 minutes___PROBLEM___Average' - - if not zabbix_url or not messages: - ins_log.read_log('error', '关键参数不能为空') - return self.write(dict(code=-1, msg='Key parameters cannot be empty')) - - with DBContext('w', None, True) as session: - session.add(ZabbixHookLog(zabbix_url=zabbix_url, logs_info='收到告警信息:{}'.format(messages))) - # 要从message里面分析数据,这里必须是强规范:{HOSTNAME}___{HOST.IP}___{TRIGGER.NAME}___{TRIGGER.STATUS}___{TRIGGER.SEVERITY} - # 我们暂时只用到这2个数据,切割后类型依次是:['Zabbix server', '127.0.0.1', 'Zabbix agent on Zabbix server is unreachable for 5 minutes', 'PROBLEM', 'Average'] - try: - messages_list = messages.split('___') - host_name, host_ip, tagger_name, tagger_status, tagger_level = messages_list[0], messages_list[1], \ - messages_list[2], messages_list[3], \ - messages_list[4] - # host_ip = messages.split('___')[1] # hostip - # tagger_name = messages.split('___')[2] # 触发器名字 - # tagger_status = messages.split('___')[3] # 触发报警状态 - # tagger_level = messages.split('___')[4] # 报警级别 - except IndexError as e: - ins_log.read_log('error', '处理告警数据格式出错:{}'.format(e)) - ins_log.read_log('error', '可能是因为你配置的规则不对,请参考模块:{}'.format(example_messages)) - - return self.write(dict(code=-1, msg='处理告警数据格式出错:{}'.format(e))) - - if not host_name or not host_ip or not tagger_name or not tagger_status or not tagger_level: - return self.write(dict(code=-1, msg='你配置的规则格式应该不正常,请参考此模板:{}'.format(example_messages))) - - # 先查询告警的主机有没有 - hook_info = session.query(ZabbixHosts.zabbix_hooks).filter(ZabbixHosts.zabbix_url == zabbix_url, - ZabbixHosts.host_name == host_name).first() - - if not hook_info: - # return self.write(dict(code=0, msg='没有匹配到主机信息')) - ins_log.read_log('info', '主机:{}, 没有匹配到信息'.format(host_name)) - return self.write(dict(code=-1, msg='[INFO]: No match to host information')) - - # 匹配到主机后开始查询是否配置钩子 - if hook_info and not hook_info[0]: - # return self.write(dict(code=0, msg='没有匹配到钩子')) - ins_log.read_log('info', '主机:{}没有匹配到钩子'.format(host_name)) - return self.write(dict(code=-1, msg='[INFO]: No match to hook')) - - else: - # 匹配到主机,并且配置了钩子 - try: - # 防止用户给的数据不能json - hook_dict = json.loads(hook_info[0]) - ins_log.read_log('info', '主机:{} 一共配置钩子数据是:{}'.format(host_name, hook_dict)) - except Exception as e: - ins_log.read_log('error', e) - session.add(ZabbixHookLog(zabbix_url=zabbix_url, logs_info='钩子出错:{}'.format(messages))) - return self.write(dict(code=2, msg='There was an error when the hook parameter was converted into ' - 'a dictionary. Please check the relevant contents carefully')) - - # 根据你的报警名称匹配你的钩子,这里一个主机你可能配置了多个钩子 - alert_title_mate = None - for i in hook_dict.keys(): - if i == tagger_name: - alert_title_mate = i - - ins_log.read_log('info', '主机:{} 本次告警匹配到的钩子是:{}'.format(host_name, alert_title_mate)) - - if not alert_title_mate: - session.add(ZabbixHookLog(zabbix_url=zabbix_url, logs_info='没有匹配到钩子'.format(messages))) - ins_log.read_log('info', '没有匹配到钩子') - return self.write(dict(code=2, msg='No hook matched')) - else: - # 开始提交任务到平台 - the_hook = hook_dict[alert_title_mate] - print(the_hook) - hook_args = dict(ZABBIX_URL=zabbix_url,HOSTIP=host_ip, HOSTNAME=host_name, TAGGER_NAME=tagger_name, - TAGGER_STATUS=tagger_status, TAGGER_LEVEL=tagger_level) - # old_hook_args = the_hook.get('hook_args') - ### 参数字典 - # hosts_dict = {1: "127.0.0.1", 2: "127.0.0.1"} ### 主机字典 - # if the_hook.get('hook_args'): - # hosts_dict.update(the_hook.get('hook_args')) - exec_host = the_hook.get('exec_host') - if exec_host: - hosts_dict = {1: exec_host} - else: - hosts_dict = {1: "127.0.0.1", 2: "127.0.0.1"} ### 主机字典 - # if old_hook_args.get('hosts_dict') and isinstance(old_hook_args.get('hosts_dict'), dict): - # hosts_dict = old_hook_args.pop('hosts_dict') - - msg = '匹配到钩子:{} 模板ID:{} 执行:{},参数:{}'.format(alert_title_mate, the_hook.get('temp_id'), - the_hook.get('schedule'), str(the_hook.get('hook_args'))) - - ins_log.read_log('info', msg) - if len(msg) > 200: - msg = msg[:200] - - session.add(ZabbixHookLog(zabbix_url=zabbix_url, logs_info=msg)) - - data_info = dict(exec_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), - task_name='ZABBIX钩子任务', temp_id=the_hook.get('temp_id'), - schedule=the_hook.get('schedule', 'ready'), - submitter=self.get_current_nickname(), args=str(hook_args), hosts=str(hosts_dict)) - - with DBContext('w', None, True) as session: - task_conf = session.query(ZabbixSubmitTaskConf.task_url, ZabbixSubmitTaskConf.auth_key).first() - - task_url = task_conf[0] - auth_key = task_conf[1] - - http_client = httpclient.AsyncHTTPClient() - cookie = {"Cookie": 'auth_key={}'.format(auth_key)} - csrf_response = await http_client.fetch(task_url, method="GET", raise_error=False, headers=cookie) - - if csrf_response.code != 200: - ins_log.read_log('error', '错误码:{}'.format(csrf_response.code)) - return self.write(dict(code=-3, msg="错误码:{}".format(csrf_response.code))) - - csrf_response_data = json.loads(csrf_response.body.decode('utf-8')) - if csrf_response_data.get('code') != 0: - ins_log.read_log('error', '权限错误:{}'.format(csrf_response_data.get('msg'))) - return self.write(dict(code=-3, msg="权限错误:{}".format(csrf_response_data.get('msg')))) - - csrf_key = csrf_response_data.get('csrf_key') - the_body = json.dumps(data_info) - cookie = {"Cookie": 'auth_key={}; csrf_key={}'.format(auth_key, csrf_key)} - response = await http_client.fetch(task_url, method="POST", body=the_body, raise_error=False, headers=cookie) - - if response.error: - ins_log.read_log('error', '请求任务接口失败:{}, 请检查参数字典格式是否正确'.format(response.error)) - return self.write(dict(code=-3, msg='请求任务接口失败:{}请检查参数字典格式是否正确'.format(response.error))) - - response_data = json.loads(response.body.decode('utf-8')) - - if response_data.get('code') != 0: - return self.write(dict(code=-1, msg=response_data.get('msg'))) - - return self.write(dict(code=0, msg=response_data.get('msg'))) - - def delete(self, *args, **kwargs): - data = json.loads(self.request.body.decode("utf-8")) - the_id = data.get('the_id') - alert_title = data.get('alert_title') - - with DBContext('w', None, True) as session: - hook_info = session.query(ZabbixHosts.zabbix_hooks).filter(ZabbixHosts.id == the_id).first() - if not hook_info: - return self.write(dict(code=-1, msg='No related items were found')) - - if not hook_info[0]: - return self.write(dict(code=-2, msg='No hooks, ignore')) - else: - try: - hook_dict = json.loads(hook_info[0]) - except Exception as e: - session.query(ZabbixHosts).filter(ZabbixHosts.id == the_id).update({ZabbixHosts.zabbix_hooks: ""}) - return self.write(dict(code=2, msg='钩子出错')) - - hook_dict.pop(alert_title) - hook_dict = json.dumps(hook_dict) - - session.query(ZabbixHosts).filter(ZabbixHosts.id == the_id).update({ZabbixHosts.zabbix_hooks: hook_dict}) - self.write(dict(code=0, msg='删除成功')) - - -zabbix_urls = [ - (r"/v1/zabbix/config/", ZabbixConfigHandler), - (r"/v1/zabbix/sync/", ZabbixSyncHandler), - (r"/v1/zabbix/tree/", ZabbixTreeHandler), - (r"/v1/zabbix/hosts/", ZabbixHostsHandler), - (r"/v1/zabbix/hooks/", ZabbixHookHandler), - (r"/v1/zabbix/logs/", ZabbixhookLogsHandler), - (r"/v1/zabbix/issues/", ZabbixLastIssuesHandler), - (r"/v1/zabbix/task_config/", ZabbixSubmitTaskConfHandler), - -] +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2019/7/4 15:55 +# @Author : Fred Yangxiaofei +# @File : zabbix_mg_handler.py +# @Role : ZABBIX相关路由 + + +import json +import datetime +from tornado import gen +from tornado import httpclient +from concurrent.futures import ThreadPoolExecutor +from tornado.concurrent import run_on_executor +from libs.database import model_to_dict +from libs.zabbix.login import zabbix_login +from libs.zabbix.get_issues import main as zabbix_last_issues +from models.zabbix_mg import ZabbixConfig, ZabbixSubmitTaskConf, ZabbixHosts, ZabbixHookLog +from websdk.db_context import DBContext +from libs.base_handler import BaseHandler +import tornado.web +from sqlalchemy import or_ +from websdk.web_logs import ins_log +from libs.zabbix.get_hosts import main as get_zabbix_hosts + + +class ZabbixTreeHandler(tornado.web.RequestHandler): + def get(self, *args, **kwargs): + hosts_list = [] + with DBContext('w') as session: + hosts_info = session.query(ZabbixHosts).all() + + for msg in hosts_info: + data_dict = model_to_dict(msg) + hosts_list.append(data_dict) + + _tree = [{"expand": True, "title": "ZABBIX", "children": [], "data_type": 'root'}] + + if hosts_list: + tmp_tree = { + "zabbix_url": {}, + "group_name": {}, + } + + for t in hosts_list: + zabbix_url, group_name = t["zabbix_url"], t['group_name'] + + # 因为是第一层所以没有parent + tmp_tree["zabbix_url"][zabbix_url] = { + "expand": True, "title": zabbix_url, "parent": "ZABBIX", "children": [], "data_type": 'zabbix_url' + } + + tmp_tree["group_name"][zabbix_url + "|" + group_name] = { + "expand": False, "title": group_name, "parent": zabbix_url, "zabbix_url": zabbix_url, + "children": [], "data_type": 'group_name' + } + + for tmp_group in tmp_tree["group_name"].values(): + tmp_tree["zabbix_url"][tmp_group["parent"]]["children"].append(tmp_group) + + for tmp_zabbix in tmp_tree["zabbix_url"].values(): + _tree[0]["children"].append(tmp_zabbix) + + return self.write(dict(code=0, msg='获取项目Tree成功', data=_tree)) + else: + return self.write(dict(code=0, msg='获取项目Tree失败', data=_tree)) + + +class ZabbixHostsHandler(tornado.web.RequestHandler): + def get(self, *args, **kwargs): + zabbix_url = self.get_argument('zabbix_url', default=None, strip=True) + group_name = self.get_argument('group_name', default=None, strip=True) + search_val = self.get_argument('search_val', default=None, strip=True) + host_list = [] + if search_val: + with DBContext('w') as session: + zabbix_host_info = session.query(ZabbixHosts).filter( + or_(ZabbixHosts.group_name.like('%{}%'.format(search_val)), + ZabbixHosts.host_name.like('%{}%'.format(search_val)), + ZabbixHosts.zabbix_url.like('%{}%'.format(search_val))) + ).order_by(ZabbixHosts.zabbix_url, ZabbixHosts.group_name).all() + + elif zabbix_url and group_name: + with DBContext('w') as session: + zabbix_host_info = session.query(ZabbixHosts).filter(ZabbixHosts.zabbix_url == zabbix_url, + ZabbixHosts.group_name == group_name).order_by( + ZabbixHosts.zabbix_url, ZabbixHosts.group_name).all() + else: + with DBContext('w') as session: + zabbix_host_info = session.query(ZabbixHosts).order_by(ZabbixHosts.zabbix_url, + ZabbixHosts.group_name).all() + + for msg in zabbix_host_info: + data_dict = model_to_dict(msg) + hook_list = [] + if data_dict['zabbix_hooks']: + git_hooks = json.loads(data_dict['zabbix_hooks']) + for k, v in git_hooks.items(): + v['alert_title'] = k + hook_list.append(v) + data_dict['hook_list'] = hook_list + host_list.append(data_dict) + + return self.write(dict(code=0, msg='获取成功', data=host_list)) + + def put(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + print('data--->',data) + alert_title = data.get('alert_title').strip() + temp_id = data.get('temp_id') + schedule = data.get('schedule', 'new') + hook_args = data.get('hook_args') + the_id = data.get('the_id') + exec_host = data.get('exec_host', '127.0.0.1') + if not alert_title or not temp_id or not the_id or not exec_host: + return self.write(dict(code=1, msg='关键参数不能为空')) + + if hook_args: + try: + hook_args_dict = json.loads(hook_args) + except Exception as e: + return self.write(dict(code=2, msg='参数字典格式不正确')) + else: + hook_args_dict = dict() + + with DBContext('w', None, True) as session: + zabbix_hooks_info = session.query(ZabbixHosts.zabbix_hooks).filter(ZabbixHosts.id == the_id).first() + hook_dict = zabbix_hooks_info[0] if zabbix_hooks_info else {} + if hook_dict: + try: + hook_dict = json.loads(hook_dict) + except Exception as e: + return self.write(dict(code=2, msg='钩子参数转化为字典的时候出错,请仔细检查相关内容' + str(e))) + + if not hook_dict: + hook_dict = {alert_title: dict(exec_host=exec_host,temp_id=temp_id, schedule=schedule, hook_args=hook_args_dict)} + else: + hook_dict[alert_title] = dict(exec_host=exec_host,temp_id=temp_id, schedule=schedule, hook_args=hook_args_dict) + + hook_dict = json.dumps(hook_dict) + + session.query(ZabbixHosts.zabbix_hooks).filter(ZabbixHosts.id == the_id).update( + {ZabbixHosts.zabbix_hooks: hook_dict}) + + self.write(dict(code=0, msg='更新钩子成功')) + + +class ZabbixConfigHandler(BaseHandler): + + def get(self, *args, **kwargs): + key = self.get_argument('key', default=None, strip=True) + value = self.get_argument('value', default=None, strip=True) + page_size = self.get_argument('page', default=1, strip=True) + limit = self.get_argument('limit', default=15, strip=True) + limit_start = (int(page_size) - 1) * int(limit) + zabbix_list = [] + with DBContext('w') as session: + if key and value: + count = session.query(ZabbixConfig).filter_by(**{key: value}).count() + zabbix_data = session.query(ZabbixConfig).filter_by(**{key: value}).order_by( + ZabbixConfig.id).offset(limit_start).limit(int(limit)) + else: + count = session.query(ZabbixConfig).count() + zabbix_data = session.query(ZabbixConfig).order_by(ZabbixConfig.id).offset( + limit_start).limit(int(limit)) + + for data in zabbix_data: + data_dict = model_to_dict(data) + zabbix_list.append(data_dict) + return self.write(dict(code=0, msg='获取成功', count=count, data=zabbix_list)) + + '''测试用户填写的信息及认证是否正确,防止主进程卡死,使用异步方法测试''' + _thread_pool = ThreadPoolExecutor(1) + + @run_on_executor(executor='_thread_pool') + def login_auth(self, zabbix_url, zabbix_username, zabbix_password): + """ + 测试ZABBIX验证是否可以通过 + :return: + """ + # 错误信息 + err_msg = '' + + ins_log.read_log('info', 'ZABBIX Login Auth') + + try: + zabbix_login(zabbix_url, zabbix_username, zabbix_password) + + except Exception as e: + err_msg = '测试失败,错误信息:{}'.format(e) + + return err_msg + + @gen.coroutine + def post(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + zabbix_name = data.get('zabbix_name', None) + zabbix_url = data.get('zabbix_url', None) + zabbix_username = data.get('zabbix_username', None) + zabbix_password = data.get('zabbix_password', None) + + if not zabbix_url or not zabbix_username or not zabbix_password: + return self.write(dict(code=-2, msg="测试必须要包含:地址、用户、密码信息")) + + msg = yield self.login_auth(zabbix_url, zabbix_username, zabbix_password) + if msg: + # 失败 + return self.write(dict(code=-1, msg=msg)) + + if not zabbix_name or not zabbix_url or not zabbix_username or not zabbix_password: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + with DBContext('w', None, True) as session: + exist_zabbix_name = session.query(ZabbixConfig).filter(ZabbixConfig.zabbix_name == zabbix_name).first() + exist_zabbix_url = session.query(ZabbixConfig).filter(ZabbixConfig.zabbix_url == zabbix_url).first() + + if exist_zabbix_name or exist_zabbix_url: + + update_info = { + "zabbix_name": zabbix_name, + "zabbix_url": zabbix_url, + "zabbix_username": zabbix_username, + "zabbix_password": zabbix_password, + } + + # 测试下编辑完后的信息是否正确 + msg = yield self.login_auth(zabbix_url, zabbix_username, zabbix_password) + if msg: + # 失败 + return self.write(dict(code=-1, msg=msg)) + + with DBContext('w', None, True) as session: + session.query(ZabbixConfig).filter(ZabbixConfig.zabbix_url == zabbix_url).update(update_info) + + return self.write(dict(code=0, msg='更新成功')) + # return self.write(dict(code=-2, msg='name或zabbix url配置信息已经存在')) + session.add( + ZabbixConfig(zabbix_name=zabbix_name, zabbix_url=zabbix_url, zabbix_username=zabbix_username, + zabbix_password=zabbix_password)) + + self.write(dict(code=0, msg='添加成功')) + + def delete(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + zabbix_config_id = data.get('id') + zabbix_url = data.get('zabbix_url') + + if not zabbix_config_id: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + with DBContext('w', None, True) as session: + session.query(ZabbixConfig).filter(ZabbixConfig.id == zabbix_config_id).delete(synchronize_session=False) + session.query(ZabbixHosts).filter(ZabbixHosts.zabbix_url == zabbix_url).delete(synchronize_session=False) + + self.write(dict(code=0, msg='删除成功')) + + +class ZabbixSyncHandler(tornado.web.RequestHandler): + '''刷新ZABBIX地址,将用户所有配置的ZABBIX信息数据都写入数据库''' + + def post(self, *args, **kwargs): + with DBContext('w', None, True) as session: + zabbix_generator_list = get_zabbix_hosts() + if zabbix_generator_list: + for zabbix_gen in zabbix_generator_list: + for host_info in zabbix_gen: + host_name = host_info.get('host_name') + exist_hostname = session.query(ZabbixHosts).filter(ZabbixHosts.host_name == host_name).first() + if not exist_hostname: + session.add( + ZabbixHosts(zabbix_url=host_info.get('zabbix_url'), group_id=host_info.get('group_id'), + group_name=host_info.get('group_name'), + host_id=host_info.get('host_id'), host_name=host_name)) + else: + session.query(ZabbixHosts).filter(ZabbixHosts.host_name == host_name).update(host_info) + session.commit() + + self.write(dict(code=0, msg='刷新成功')) + + +class ZabbixLastIssuesHandler(tornado.web.RequestHandler): + '''获取多ZABBIX ISSUES信息,前端展示出来''' + + def get(self, *args, **kwargs): + last_issues = zabbix_last_issues() + return self.write(dict(code=0, msg='获取成功', data=last_issues)) + + +class ZabbixhookLogsHandler(tornado.web.RequestHandler): + '''获取webhook告警日志''' + + @gen.coroutine + def get(self, *args, **kwargs): + log_list = [] + + with DBContext('w') as session: + hooks_log_info = session.query(ZabbixHookLog).order_by(-ZabbixHookLog.id).limit(200).all() + + for msg in hooks_log_info: + data_dict = model_to_dict(msg) + data_dict['create_time'] = str(data_dict['create_time']) + log_list.append(data_dict) + + return self.write(dict(code=0, msg='获取成功', data=log_list)) + + +class ZabbixSubmitTaskConfHandler(tornado.web.RequestHandler): + '''ZABBIX钩子向任务平台提交任务,需要一个认证''' + + def get(self, *args, **kwargs): + page_size = self.get_argument('page', default=1, strip=True) + limit = self.get_argument('limit', default=1, strip=True) + limit_start = (int(page_size) - 1) * int(limit) # 只能有一条 + submit_task_conf_list = [] + with DBContext('w') as session: + zabbix_submit_task_conf_data = session.query(ZabbixSubmitTaskConf).order_by(ZabbixSubmitTaskConf.id).offset( + limit_start).limit(int(limit)) + for data in zabbix_submit_task_conf_data: + data_dict = model_to_dict(data) + submit_task_conf_list.append(data_dict) + return self.write(dict(code=0, msg='获取成功', data=submit_task_conf_list)) + + async def post(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + task_url = data.get('task_url', None) + auth_key = data.get('auth_key', None) + + if not task_url or not auth_key: + return self.write(dict(code=-2, msg="测试必须要包含:task_url、auth_key信息")) + + # 测试下权限 + http_client = httpclient.AsyncHTTPClient() + cookie = {"Cookie": 'auth_key={}'.format(auth_key)} + response = await http_client.fetch(task_url, method="GET", raise_error=False, headers=cookie) + + if response.code != 200: + return self.write(dict(code=-3, msg="错误码:{}".format(response.code))) + + response_data = json.loads(response.body.decode('utf-8')) + if response_data.get('code') != 0: + return self.write(dict(code=-3, msg="权限错误:{}".format(response_data.get('msg')))) + + # + with DBContext('w', None, True) as session: + exist_config = session.query(ZabbixSubmitTaskConf.id).first() + if not exist_config: + session.add(ZabbixSubmitTaskConf(task_url=task_url, auth_key=auth_key)) + else: + return self.write(dict(code=-4, msg="提交任务的认证配置信息只能存在一条")) + + self.write(dict(code=0, msg='添加成功')) + + def delete(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + submit_task_config_id = data.get('id') + + if not submit_task_config_id: + return self.write(dict(code=-2, msg='关键参数不能为空')) + + with DBContext('w', None, True) as session: + session.query(ZabbixSubmitTaskConf).filter(ZabbixSubmitTaskConf.id == submit_task_config_id).delete( + synchronize_session=False) + self.write(dict(code=0, msg='删除成功')) + + +class ZabbixHookHandler(BaseHandler): + @gen.coroutine + def get(self, *args, **kwargs): + self.write(dict(code=0, msg='获取csrf_key成功', csrf_key=self.new_csrf_key)) + + async def post(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + + print('data----->',data) + ins_log.read_log('info', '接收到数据:{}'.format(data)) + zabbix_url = data.get('zabbix_url') + messages = data.get('messages') + example_messages = 'Zabbix server___127.0.0.1___Zabbix agent on Zabbix server is unreachable for 5 minutes___PROBLEM___Average' + + if not zabbix_url or not messages: + ins_log.read_log('error', '关键参数不能为空') + return self.write(dict(code=-1, msg='Key parameters cannot be empty')) + + with DBContext('w', None, True) as session: + session.add(ZabbixHookLog(zabbix_url=zabbix_url, logs_info='收到告警信息:{}'.format(messages))) + # 要从message里面分析数据,这里必须是强规范:{HOSTNAME}___{HOST.IP}___{TRIGGER.NAME}___{TRIGGER.STATUS}___{TRIGGER.SEVERITY} + # 我们暂时只用到这2个数据,切割后类型依次是:['Zabbix server', '127.0.0.1', 'Zabbix agent on Zabbix server is unreachable for 5 minutes', 'PROBLEM', 'Average'] + try: + messages_list = messages.split('___') + host_name, host_ip, tagger_name, tagger_status, tagger_level = messages_list[0], messages_list[1], \ + messages_list[2], messages_list[3], \ + messages_list[4] + # host_ip = messages.split('___')[1] # hostip + # tagger_name = messages.split('___')[2] # 触发器名字 + # tagger_status = messages.split('___')[3] # 触发报警状态 + # tagger_level = messages.split('___')[4] # 报警级别 + except IndexError as e: + ins_log.read_log('error', '处理告警数据格式出错:{}'.format(e)) + ins_log.read_log('error', '可能是因为你配置的规则不对,请参考模块:{}'.format(example_messages)) + + return self.write(dict(code=-1, msg='处理告警数据格式出错:{}'.format(e))) + + if not host_name or not host_ip or not tagger_name or not tagger_status or not tagger_level: + return self.write(dict(code=-1, msg='你配置的规则格式应该不正常,请参考此模板:{}'.format(example_messages))) + + # 先查询告警的主机有没有 + hook_info = session.query(ZabbixHosts.zabbix_hooks).filter(ZabbixHosts.zabbix_url == zabbix_url, + ZabbixHosts.host_name == host_name).first() + + if not hook_info: + # return self.write(dict(code=0, msg='没有匹配到主机信息')) + ins_log.read_log('info', '主机:{}, 没有匹配到信息'.format(host_name)) + return self.write(dict(code=-1, msg='[INFO]: No match to host information')) + + # 匹配到主机后开始查询是否配置钩子 + if hook_info and not hook_info[0]: + # return self.write(dict(code=0, msg='没有匹配到钩子')) + ins_log.read_log('info', '主机:{}没有匹配到钩子'.format(host_name)) + return self.write(dict(code=-1, msg='[INFO]: No match to hook')) + + else: + # 匹配到主机,并且配置了钩子 + try: + # 防止用户给的数据不能json + hook_dict = json.loads(hook_info[0]) + ins_log.read_log('info', '主机:{} 一共配置钩子数据是:{}'.format(host_name, hook_dict)) + except Exception as e: + ins_log.read_log('error', e) + session.add(ZabbixHookLog(zabbix_url=zabbix_url, logs_info='钩子出错:{}'.format(messages))) + return self.write(dict(code=2, msg='There was an error when the hook parameter was converted into ' + 'a dictionary. Please check the relevant contents carefully')) + + # 根据你的报警名称匹配你的钩子,这里一个主机你可能配置了多个钩子 + alert_title_mate = None + for i in hook_dict.keys(): + if i == tagger_name: + alert_title_mate = i + + ins_log.read_log('info', '主机:{} 本次告警匹配到的钩子是:{}'.format(host_name, alert_title_mate)) + + if not alert_title_mate: + session.add(ZabbixHookLog(zabbix_url=zabbix_url, logs_info='没有匹配到钩子'.format(messages))) + ins_log.read_log('info', '没有匹配到钩子') + return self.write(dict(code=2, msg='No hook matched')) + else: + # 开始提交任务到平台 + the_hook = hook_dict[alert_title_mate] + print(the_hook) + hook_args = dict(ZABBIX_URL=zabbix_url,HOSTIP=host_ip, HOSTNAME=host_name, TAGGER_NAME=tagger_name, + TAGGER_STATUS=tagger_status, TAGGER_LEVEL=tagger_level) + # old_hook_args = the_hook.get('hook_args') + ### 参数字典 + # hosts_dict = {1: "127.0.0.1", 2: "127.0.0.1"} ### 主机字典 + # if the_hook.get('hook_args'): + # hosts_dict.update(the_hook.get('hook_args')) + exec_host = the_hook.get('exec_host') + if exec_host: + hosts_dict = {1: exec_host} + else: + hosts_dict = {1: "127.0.0.1", 2: "127.0.0.1"} ### 主机字典 + # if old_hook_args.get('hosts_dict') and isinstance(old_hook_args.get('hosts_dict'), dict): + # hosts_dict = old_hook_args.pop('hosts_dict') + + msg = '匹配到钩子:{} 模板ID:{} 执行:{},参数:{}'.format(alert_title_mate, the_hook.get('temp_id'), + the_hook.get('schedule'), str(the_hook.get('hook_args'))) + + ins_log.read_log('info', msg) + if len(msg) > 200: + msg = msg[:200] + + session.add(ZabbixHookLog(zabbix_url=zabbix_url, logs_info=msg)) + + data_info = dict(exec_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), + task_name='ZABBIX钩子任务', temp_id=the_hook.get('temp_id'), + schedule=the_hook.get('schedule', 'ready'), + submitter=self.get_current_nickname(), args=str(hook_args), hosts=str(hosts_dict)) + + with DBContext('w', None, True) as session: + task_conf = session.query(ZabbixSubmitTaskConf.task_url, ZabbixSubmitTaskConf.auth_key).first() + + task_url = task_conf[0] + auth_key = task_conf[1] + + http_client = httpclient.AsyncHTTPClient() + cookie = {"Cookie": 'auth_key={}'.format(auth_key)} + csrf_response = await http_client.fetch(task_url, method="GET", raise_error=False, headers=cookie) + + if csrf_response.code != 200: + ins_log.read_log('error', '错误码:{}'.format(csrf_response.code)) + return self.write(dict(code=-3, msg="错误码:{}".format(csrf_response.code))) + + csrf_response_data = json.loads(csrf_response.body.decode('utf-8')) + if csrf_response_data.get('code') != 0: + ins_log.read_log('error', '权限错误:{}'.format(csrf_response_data.get('msg'))) + return self.write(dict(code=-3, msg="权限错误:{}".format(csrf_response_data.get('msg')))) + + csrf_key = csrf_response_data.get('csrf_key') + the_body = json.dumps(data_info) + cookie = {"Cookie": 'auth_key={}; csrf_key={}'.format(auth_key, csrf_key)} + response = await http_client.fetch(task_url, method="POST", body=the_body, raise_error=False, headers=cookie) + + if response.error: + ins_log.read_log('error', '请求任务接口失败:{}, 请检查参数字典格式是否正确'.format(response.error)) + return self.write(dict(code=-3, msg='请求任务接口失败:{}请检查参数字典格式是否正确'.format(response.error))) + + response_data = json.loads(response.body.decode('utf-8')) + + if response_data.get('code') != 0: + return self.write(dict(code=-1, msg=response_data.get('msg'))) + + return self.write(dict(code=0, msg=response_data.get('msg'))) + + def delete(self, *args, **kwargs): + data = json.loads(self.request.body.decode("utf-8")) + the_id = data.get('the_id') + alert_title = data.get('alert_title') + + with DBContext('w', None, True) as session: + hook_info = session.query(ZabbixHosts.zabbix_hooks).filter(ZabbixHosts.id == the_id).first() + if not hook_info: + return self.write(dict(code=-1, msg='No related items were found')) + + if not hook_info[0]: + return self.write(dict(code=-2, msg='No hooks, ignore')) + else: + try: + hook_dict = json.loads(hook_info[0]) + except Exception as e: + session.query(ZabbixHosts).filter(ZabbixHosts.id == the_id).update({ZabbixHosts.zabbix_hooks: ""}) + return self.write(dict(code=2, msg='钩子出错')) + + hook_dict.pop(alert_title) + hook_dict = json.dumps(hook_dict) + + session.query(ZabbixHosts).filter(ZabbixHosts.id == the_id).update({ZabbixHosts.zabbix_hooks: hook_dict}) + self.write(dict(code=0, msg='删除成功')) + + +zabbix_urls = [ + (r"/v1/zabbix/config/", ZabbixConfigHandler), + (r"/v1/zabbix/sync/", ZabbixSyncHandler), + (r"/v1/zabbix/tree/", ZabbixTreeHandler), + (r"/v1/zabbix/hosts/", ZabbixHostsHandler), + (r"/v1/zabbix/hooks/", ZabbixHookHandler), + (r"/v1/zabbix/logs/", ZabbixhookLogsHandler), + (r"/v1/zabbix/issues/", ZabbixLastIssuesHandler), + (r"/v1/zabbix/task_config/", ZabbixSubmitTaskConfHandler), + +] diff --git a/biz/paid_write_redis.py b/biz/paid_write_redis.py index 922c528..6488500 100644 --- a/biz/paid_write_redis.py +++ b/biz/paid_write_redis.py @@ -1,194 +1,194 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2019/3/21 12:56 -# @Author : Fred Yangxiaofei -# @File : paid_write_redis.py -# @Role : 用于提醒,如:将要过期的电信线路 - - -import json -from libs.database import model_to_dict -from libs.database import db_session -from libs.redis_connect import redis_conn -from biz.get_userinfo import get_user_info -from models.paid_mg import PaidMG -import datetime -from websdk.consts import const -from websdk.utils import SendMail - - -def get_paid_info(): - """ - 获取付费管理信息 - :return: - """ - paid_list = [] - paid_data = db_session.query(PaidMG).all() - db_session.close() - - - for data in paid_data: - data_dict = model_to_dict(data) - data_dict['paid_start_time'] = str(data_dict['paid_start_time']) - data_dict['paid_end_time'] = str(data_dict['paid_end_time']) - data_dict['create_at'] = str(data_dict['create_at']) - data_dict['update_at'] = str(data_dict['update_at']) - paid_list.append(data_dict) - return paid_list - - -def save_data(): - """ - 提醒内容写入redis - :return: - """ - - # 付费信息 - paid_data = get_paid_info() - # CODO用户信息 - user_data = get_user_info() - userdata = [json.loads(x) for x in user_data] - with redis_conn.pipeline(transaction=False) as p: - for remind in paid_data: - # print(remind) - for u in userdata: - if remind.get('nicknames'): - if u.get('nickname') in remind.get('nicknames').split(','): - #print(remind.get('paid_name'), {u.get('tel'): u.get('email')}) - save_data = {u.get('tel'): u.get('email')} - p.hmset(remind.get('paid_name'), save_data) - p.execute() - - - -def check_reminder(): - """ - 用途: - 检查哪些事件需要进行邮件提醒 - 逻辑: - 这里逻辑简单说明下如下: - 01. 先获取到所有事件的到期时间 - 02. 获取所有事件中每条事件都需要提前多少天进行提醒 - 03. 计算从哪天开始进行提醒(过期时间 - 提前提醒天数 = 开始提醒的日期) - 04. 计算出来的·开始提醒日期· <= 现在时间 都进行报警 - :return: - """ - # 邮箱配置信息 - config_info = redis_conn.hgetall(const.APP_SETTINGS) - sm = SendMail(mail_host=config_info.get(const.EMAIL_HOST), mail_port=config_info.get(const.EMAIL_PORT), - mail_user=config_info.get(const.EMAIL_HOST_USER), - mail_password=config_info.get(const.EMAIL_HOST_PASSWORD), - mail_ssl=True if config_info.get(const.EMAIL_USE_SSL) == '1' else False) - - for msg in db_session.query(PaidMG).all(): - if msg.paid_end_time < datetime.datetime.now(): - email_content = '{}已过期,请删除该提醒'.format(msg.paid_name) - exp_paid_name = msg.paid_name - emails_list = redis_conn.hvals(msg.paid_name) - sm.send_mail(",".join(emails_list),'运维提醒信息',email_content) - reminder_time = msg.paid_end_time - datetime.timedelta(days=int(msg.reminder_day)) - if reminder_time <= datetime.datetime.now(): - if msg.paid_name != exp_paid_name: - remainder_time = msg.paid_end_time - datetime.datetime.now() - email_content = ('{}还有{}天到期,请留意'.format(msg.paid_name, remainder_time.days)) - emails_list = redis_conn.hvals(msg.paid_name) - sm.send_mail(",".join(emails_list), '运维提醒信息', email_content) - # print('msg_name---->',msg.paid_name) - # print('email_list---->',emails_list) - # content = """ - # - # - #
- # - #名称 | - #过期时间 | - #提前通知天数 | - #
{} | - #{} | - #{} | - #