mirror of https://github.com/openspug/spug
fix issue
parent
8c95bc35f7
commit
fa56af614b
|
@ -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(), []
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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', '发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的企业微信。')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue