fix issue

pull/410/head
vapao 2021-10-14 20:55:25 +08:00
parent 8c95bc35f7
commit fa56af614b
3 changed files with 100 additions and 36 deletions

View File

@ -4,9 +4,8 @@
from django_redis import get_redis_connection from django_redis import get_redis_connection
from django.conf import settings from django.conf import settings
from libs.utils import human_datetime from libs.utils import human_datetime
from libs.spug import Notification
from apps.host.models import Host from apps.host.models import Host
from apps.notify.models import Notify
import requests
import subprocess import subprocess
import json import json
import os import os
@ -23,7 +22,7 @@ class Helper:
self.rds.delete(self.key) self.rds.delete(self.key)
@classmethod @classmethod
def _make_dd_notify(cls, action, req, version, host_str): def _make_dd_notify(cls, url, action, req, version, host_str):
texts = [ texts = [
f'**申请标题:** {req.name}', f'**申请标题:** {req.name}',
f'**应用名称:** {req.deploy.app.name}', f'**应用名称:** {req.deploy.app.name}',
@ -60,16 +59,17 @@ class Helper:
f'**发布时间:** {human_datetime()}', f'**发布时间:** {human_datetime()}',
'> 来自 Spug运维平台' '> 来自 Spug运维平台'
]) ])
return { data = {
'msgtype': 'markdown', 'msgtype': 'markdown',
'markdown': { 'markdown': {
'title': 'Spug 发布消息通知', 'title': 'Spug 发布消息通知',
'text': '\n\n'.join(texts) 'text': '\n\n'.join(texts)
} }
} }
Notification.handle_request(url, data, 'dd')
@classmethod @classmethod
def _make_wx_notify(cls, action, req, version, host_str): def _make_wx_notify(cls, url, action, req, version, host_str):
texts = [ texts = [
f'申请标题: {req.name}', f'申请标题: {req.name}',
f'应用名称: {req.deploy.app.name}', f'应用名称: {req.deploy.app.name}',
@ -107,25 +107,76 @@ class Helper:
f'发布时间: {human_datetime()}', f'发布时间: {human_datetime()}',
'> 来自 Spug运维平台' '> 来自 Spug运维平台'
]) ])
return { data = {
'msgtype': 'markdown', 'msgtype': 'markdown',
'markdown': { 'markdown': {
'content': '\n'.join(texts) 'content': '\n'.join(texts)
} }
} }
Notification.handle_request(url, data, 'wx')
@classmethod
def _make_fs_notify(cls, url, action, req, version, host_str):
texts = [
f'申请标题: {req.name}',
f'应用名称: {req.deploy.app.name}',
f'应用版本: {version}',
f'发布环境: {req.deploy.env.name}',
f'发布主机: {host_str}',
]
if action == 'approve_req':
title = '发布审核申请'
texts.extend([
f'申请人员: {req.created_by.nickname}',
f'申请时间: {human_datetime()}',
])
elif action == 'approve_rst':
title = '发布审核结果'
text = '通过' if req.status == '1' else '驳回'
texts.extend([
f'审核人员: {req.approve_by.nickname}',
f'审核结果: {text}',
f'审核意见: {req.reason or ""}',
f'审核时间: {human_datetime()}',
])
else:
title = '发布结果通知'
text = '成功 ✅' if req.status == '3' else '失败 ❗'
if req.approve_at:
texts.append(f'审核人员: {req.approve_by.nickname}')
do_user = req.do_by.nickname if req.type != '3' else 'Webhook'
texts.extend([
f'执行人员: {do_user}',
f'发布结果: {text}',
f'发布时间: {human_datetime()}',
])
data = {
'msg_type': 'post',
'content': {
'post': {
'zh_cn': {
'title': title,
'content': [[{'tag': 'text', 'text': x}] for x in texts] + [[{'tag': 'at', 'user_id': 'all'}]]
}
}
}
}
Notification.handle_request(url, data, 'fs')
@classmethod @classmethod
def send_deploy_notify(cls, req, action=None): def send_deploy_notify(cls, req, action=None):
rst_notify = json.loads(req.deploy.rst_notify) rst_notify = json.loads(req.deploy.rst_notify)
host_ids = json.loads(req.host_ids) host_ids = json.loads(req.host_ids)
if rst_notify['mode'] != '0' and rst_notify.get('value'): if rst_notify['mode'] != '0' and rst_notify.get('value'):
url = rst_notify['value']
version = req.version version = req.version
hosts = [{'id': x.id, 'name': x.name} for x in Host.objects.filter(id__in=host_ids)] hosts = [{'id': x.id, 'name': x.name} for x in Host.objects.filter(id__in=host_ids)]
host_str = ', '.join(x['name'] for x in hosts[:2]) host_str = ', '.join(x['name'] for x in hosts[:2])
if len(hosts) > 2: if len(hosts) > 2:
host_str += f'{len(hosts)}台主机' host_str += f'{len(hosts)}台主机'
if rst_notify['mode'] == '1': if rst_notify['mode'] == '1':
data = cls._make_dd_notify(action, req, version, host_str) cls._make_dd_notify(url, action, req, version, host_str)
elif rst_notify['mode'] == '2': elif rst_notify['mode'] == '2':
data = { data = {
'action': action, 'action': action,
@ -142,17 +193,13 @@ class Helper:
'is_success': req.status == '3', 'is_success': req.status == '3',
'created_at': human_datetime() 'created_at': human_datetime()
} }
Notification.handle_request(url, data)
elif rst_notify['mode'] == '3': elif rst_notify['mode'] == '3':
data = cls._make_wx_notify(action, req, version, host_str) cls._make_wx_notify(url, action, req, version, host_str)
elif rst_notify['mode'] == '4':
cls._make_fs_notify(url, action, req, version, host_str)
else: else:
raise NotImplementedError raise NotImplementedError
res = requests.post(rst_notify['value'], json=data)
if res.status_code != 200:
Notify.make_notify('flag', '1', '发布通知发送失败', f'返回状态码:{res.status_code}, 请求URL{res.url}')
if rst_notify['mode'] in ['1', '3']:
res = res.json()
if res.get('errcode') != 0:
Notify.make_notify('flag', '1', '发布通知发送失败', f'返回数据:{res}')
def parse_filter_rule(self, data: str, sep='\n'): def parse_filter_rule(self, data: str, sep='\n'):
data, files = data.strip(), [] data, files = data.strip(), []

View File

@ -1,10 +1,9 @@
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug # Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
# Copyright: (c) <spug.dev@gmail.com> # Copyright: (c) <spug.dev@gmail.com>
# Released under the AGPL-3.0 License. # Released under the AGPL-3.0 License.
from apps.notify.models import Notify
from libs.utils import human_datetime from libs.utils import human_datetime
from libs.spug import Notification
from threading import Thread from threading import Thread
import requests
import json import json
@ -36,6 +35,7 @@ def _do_notify(task, mode, url, msg):
'isAtAll': True 'isAtAll': True
} }
} }
Notification.handle_request(url, data, 'dd')
elif mode == '2': elif mode == '2':
data = { data = {
'task_id': task.id, 'task_id': task.id,
@ -44,6 +44,7 @@ def _do_notify(task, mode, url, msg):
'message': msg or '请在任务计划执行历史中查看详情', 'message': msg or '请在任务计划执行历史中查看详情',
'created_at': human_datetime() 'created_at': human_datetime()
} }
Notification.handle_request(url, data)
elif mode == '3': elif mode == '3':
texts = [ texts = [
'## <font color="warning">任务执行失败通知</font>', '## <font color="warning">任务执行失败通知</font>',
@ -59,12 +60,23 @@ def _do_notify(task, mode, url, msg):
'content': '\n'.join(texts) 'content': '\n'.join(texts)
} }
} }
else: Notification.handle_request(url, data, 'wx')
return elif mode == '4':
res = requests.post(url, json=data) data = {
if res.status_code != 200: 'msg_type': 'post',
Notify.make_notify('schedule', '1', '任务执行通知发送失败', f'返回状态码:{res.status_code}, 请求URL{url}') 'content': {
if mode in ['1', '3']: 'post': {
res = res.json() 'zh_cn': {
if res.get('errcode') != 0: 'title': '任务执行失败通知',
Notify.make_notify('schedule', '1', '任务执行通知发送失败', f'返回数据:{res}') 'content': [
[{'tag': 'text', 'text': f'任务名称: {task.name}'}],
[{'tag': 'text', 'text': f'任务类型: {task.type}'}],
[{'tag': 'text', 'text': f'描述信息: {msg or "请在任务计划执行历史中查看详情"}'}],
[{'tag': 'text', 'text': f'发生时间: {human_datetime()}'}],
[{'tag': 'at', 'user_id': 'all'}],
]
}
}
}
}
Notification.handle_request(url, data, 'fs')

View File

@ -38,22 +38,27 @@ class Notification:
spug_key = AppSetting.get_default('spug_key') spug_key = AppSetting.get_default('spug_key')
return spug_key, sum([json.loads(x.contacts) for x in Group.objects.filter(id__in=grp)], []) return spug_key, sum([json.loads(x.contacts) for x in Group.objects.filter(id__in=grp)], [])
def _handle_request(self, mode, url, data): @staticmethod
def handle_request(url, data, mode=None):
try: try:
res = requests.post(url, json=data, timeout=30) res = requests.post(url, json=data, timeout=30)
except Exception as e: except Exception as e:
Notify.make_notify(notify_source, '1', '告警通知发送失败', f'接口调用异常:{e}') Notify.make_notify(notify_source, '1', '通知发送失败', f'接口调用异常:{e}')
return return
if res.status_code != 200: if res.status_code != 200:
Notify.make_notify(notify_source, '1', '告警通知发送失败', f'返回状态码:{res.status_code}, 请求URL{res.url}') Notify.make_notify(notify_source, '1', '通知发送失败', f'返回状态码:{res.status_code}, 请求URL{res.url}')
if mode in ['dd', 'wx']: if mode in ['dd', 'wx']:
res = res.json() res = res.json()
if res.get('errcode') != 0: if res.get('errcode') != 0:
Notify.make_notify(notify_source, '1', '告警通知发送失败', f'返回数据:{res}') Notify.make_notify(notify_source, '1', '通知发送失败', f'返回数据:{res}')
if mode == 'spug': elif mode == 'spug':
res = res.json() res = res.json()
if res.get('error'): if res.get('error'):
Notify.make_notify(notify_source, '1', '告警通知发送失败', f'错误信息:{res}') Notify.make_notify(notify_source, '1', '通知发送失败', f'错误信息:{res}')
elif mode == 'fs':
res = res.json()
if res.get('StatusCode') != 0:
Notify.make_notify(notify_source, '1', '通知发送失败', f'错误信息:{res}')
def _by_wx(self): def _by_wx(self):
if not self.spug_key: if not self.spug_key:
@ -69,7 +74,7 @@ class Notification:
'remark': f'故障持续{self.duration}' if self.event == '2' else None, 'remark': f'故障持续{self.duration}' if self.event == '2' else None,
'users': list(users) 'users': list(users)
} }
self._handle_request('spug', f'{spug_server}/apis/notify/wx/', data) self.handle_request(f'{spug_server}/apis/notify/wx/', data, 'spug')
else: else:
Notify.make_notify(notify_source, '1', '发送报警信息失败', '未找到可用的通知对象请确保设置了相关报警联系人的微信Token。') Notify.make_notify(notify_source, '1', '发送报警信息失败', '未找到可用的通知对象请确保设置了相关报警联系人的微信Token。')
@ -98,7 +103,7 @@ class Notification:
'body': '\r\n'.join(body), 'body': '\r\n'.join(body),
'users': list(users) 'users': list(users)
} }
self._handle_request('spug', f'{spug_server}/apis/notify/mail/', data) self.handle_request(f'{spug_server}/apis/notify/mail/', data, 'spug')
else: else:
Notify.make_notify(notify_source, '1', '发送报警信息失败', '未配置报警服务调用凭据,请在系统管理/系统设置/报警服务设置中配置。') Notify.make_notify(notify_source, '1', '发送报警信息失败', '未配置报警服务调用凭据,请在系统管理/系统设置/报警服务设置中配置。')
else: else:
@ -127,7 +132,7 @@ class Notification:
} }
} }
for url in users: for url in users:
self._handle_request('dd', url, data) self.handle_request(url, data, 'dd')
else: else:
Notify.make_notify(notify_source, '1', '发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的钉钉。') Notify.make_notify(notify_source, '1', '发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的钉钉。')
@ -151,7 +156,7 @@ class Notification:
} }
} }
for url in users: for url in users:
self._handle_request('wx', url, data) self.handle_request(url, data, 'wx')
else: else:
Notify.make_notify(notify_source, '1', '发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的企业微信。') Notify.make_notify(notify_source, '1', '发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的企业微信。')