A 添加报警联系人的发送报警测试功能

pull/442/head
vapao 2021-12-19 23:27:42 +08:00
parent 9a03bccb88
commit d9d5410852
4 changed files with 91 additions and 22 deletions

View File

@ -9,4 +9,5 @@ urlpatterns = [
path('alarm/', AlarmView.as_view()),
path('group/', GroupView.as_view()),
path('contact/', ContactView.as_view()),
path('test/', handle_test),
]

View File

@ -3,6 +3,7 @@
# Released under the AGPL-3.0 License.
from django.views.generic import View
from libs import json_response, JsonParser, Argument, auth
from libs.spug import Notification
from apps.alarm.models import Alarm, Group, Contact
from apps.monitor.models import Detection
import json
@ -87,3 +88,29 @@ class ContactView(View):
return json_response(error=f'报警联系组【{group.name}】包含此联系人,请解除关联后再尝试删除该联系人')
Contact.objects.filter(pk=form.id).delete()
return json_response(error=error)
@auth('alarm.contact.add|alarm.contact.edit')
def handle_test(request):
form, error = JsonParser(
Argument('mode', help='参数错误'),
Argument('value', help='参数错误')
).parse(request.body)
if error is None:
notify = Notification(None, '1', 'https://spug.cc', 'Spug官网测试', '这是一条测试告警信息', None)
if form.mode in ('1', '2', '4') and not notify.spug_key:
return json_response(error='未配置调用凭据(系统设置/基本设置),请配置后再尝试。')
if form.mode == '1':
notify.monitor_by_wx([form.value])
elif form.mode == '2':
return json_response(error='目前暂不支持短信告警,请关注后续更新。')
elif form.mode == '3':
notify.monitor_by_dd([form.value])
elif form.mode == '4':
notify.monitor_by_email([form.value])
elif form.mode == '5':
notify.monitor_by_qy_wx([form.value])
else:
return json_response(error='不支持的报警方式')
return json_response(error=error)

View File

@ -27,16 +27,14 @@ def send_login_wx_code(wx_token, code):
class Notification:
def __init__(self, grp, event, target, title, message, duration):
self.grp = grp
self.event = event
self.title = title
self.target = target
self.message = message
self.duration = duration
self.spug_key, self.u_ids = self._parse_args(grp)
def _parse_args(self, grp):
spug_key = AppSetting.get_default('spug_key')
return spug_key, sum([json.loads(x.contacts) for x in Group.objects.filter(id__in=grp)], [])
self.spug_key = AppSetting.get_default('spug_key')
self.u_ids = []
@staticmethod
def handle_request(url, data, mode=None):
@ -63,7 +61,7 @@ class Notification:
raise NotImplementedError
Notify.make_system_notify('通知发送失败', f'返回数据:{res}')
def _monitor_by_wx(self, users):
def monitor_by_wx(self, users):
if not self.spug_key:
Notify.make_monitor_notify('发送报警信息失败', '未配置报警服务调用凭据,请在系统管理/系统设置/基本设置/调用凭据中配置。')
return
@ -77,7 +75,7 @@ class Notification:
}
self.handle_request(f'{spug_server}/apis/notify/wx/', data, 'spug')
def _monitor_by_email(self, users):
def monitor_by_email(self, users):
mail_service = AppSetting.get_default('mail_service', {})
body = [
f'告警名称:{self.title}',
@ -104,7 +102,7 @@ class Notification:
else:
Notify.make_monitor_notify('发送报警信息失败', '未配置报警服务调用凭据,请在系统管理/系统设置/报警服务设置中配置。')
def _monitor_by_dd(self, users):
def monitor_by_dd(self, users):
texts = [
'## %s ## ' % ('监控告警通知' if self.event == '1' else '告警恢复通知'),
f'**告警名称:** <font color="#{"f90202" if self.event == "1" else "008000"}">{self.title}</font> ',
@ -127,7 +125,7 @@ class Notification:
for url in users:
self.handle_request(url, data, 'dd')
def _monitor_by_qy_wx(self, users):
def monitor_by_qy_wx(self, users):
color, title = ('warning', '监控告警通知') if self.event == '1' else ('info', '告警恢复通知')
texts = [
f'## {title}',
@ -148,28 +146,29 @@ class Notification:
self.handle_request(url, data, 'wx')
def dispatch_monitor(self, modes):
self.u_ids = sum([json.loads(x.contacts) for x in Group.objects.filter(id__in=self.grp)], [])
for mode in modes:
if mode == '1':
users = set(x.wx_token for x in Contact.objects.filter(id__in=self.u_ids, wx_token__isnull=False))
if not users:
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象请确保设置了相关报警联系人的微信Token。')
continue
self._monitor_by_wx(users)
self.monitor_by_wx(users)
elif mode == '3':
users = set(x.ding for x in Contact.objects.filter(id__in=self.u_ids, ding__isnull=False))
if not users:
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的钉钉。')
continue
self._monitor_by_dd(users)
self.monitor_by_dd(users)
elif mode == '4':
users = set(x.email for x in Contact.objects.filter(id__in=self.u_ids, email__isnull=False))
if not users:
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的邮件地址。')
continue
self._monitor_by_email(users)
self.monitor_by_email(users)
elif mode == '5':
users = set(x.qy_wx for x in Contact.objects.filter(id__in=self.u_ids, qy_wx__isnull=False))
if not users:
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的企业微信。')
continue
self._monitor_by_qy_wx(users)
self.monitor_by_qy_wx(users)

View File

@ -5,13 +5,15 @@
*/
import React, { useState } from 'react';
import { observer } from 'mobx-react';
import { Modal, Form, Input, message } from 'antd';
import { Modal, Form, Input, Tooltip, message } from 'antd';
import { ThunderboltOutlined, LoadingOutlined } from '@ant-design/icons';
import http from 'libs/http';
import store from './store';
export default observer(function () {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
const [testLoading, setTestLoading] = useState('0');
function handleSubmit() {
setLoading(true);
@ -25,6 +27,34 @@ export default observer(function () {
}, () => setLoading(false))
}
function handleTest(mode, name) {
const value = form.getFieldValue(name)
console.log(name, value)
if (!value) return message.error('请输入后再执行测试')
setTestLoading(mode)
http.post('/api/alarm/test/', {mode, value})
.then(() => {
message.success('执行成功')
})
.finally(() => setTestLoading('0'))
}
function Test(props) {
return (
<div style={{position: 'absolute', right: -30, top: 8}}>
{testLoading === props.mode ? (
<LoadingOutlined style={{fontSize: 18, color: '#faad14'}}/>
) : (
<Tooltip title="执行测试">
<ThunderboltOutlined
style={{fontSize: 18, color: '#faad14'}}
onClick={() => handleTest(props.mode, props.name)}/>
</Tooltip>
)}
</div>
)
}
return (
<Modal
visible
@ -41,23 +71,35 @@ export default observer(function () {
<Form.Item name="phone" label="手机号">
<Input placeholder="请输入手机号"/>
</Form.Item>
<Form.Item name="email" label="邮箱">
<Input placeholder="请输入邮箱地址"/>
<Form.Item label="邮箱">
<Form.Item noStyle name="email">
<Input placeholder="请输入邮箱地址"/>
</Form.Item>
<Test mode="4" name="email"/>
</Form.Item>
<Form.Item name="wx_token" label="微信Token" extra={
<Form.Item label="微信Token" extra={
<a target="_blank" rel="noopener noreferrer"
href="https://spug.cc/docs/alarm-contact/">如何获取微信 Token </a>}>
<Input placeholder="请输入微信token"/>
<Form.Item noStyle name="wx_token">
<Input placeholder="请输入微信token"/>
</Form.Item>
<Test mode="1" name="wx_token"/>
</Form.Item>
<Form.Item name="ding" label="钉钉" extra={<span>
<Form.Item label="钉钉" extra={<span>
钉钉收不到通知请参考
<a target="_blank" rel="noopener noreferrer"
href="https://spug.cc/docs/install-error/#%E9%92%89%E9%92%89%E6%94%B6%E4%B8%8D%E5%88%B0%E9%80%9A%E7%9F%A5%EF%BC%9F">官方文档</a>
</span>}>
<Input placeholder="https://oapi.dingtalk.com/robot/send?access_token=xxx"/>
<Form.Item noStyle name="ding">
<Input placeholder="https://oapi.dingtalk.com/robot/send?access_token=xxx"/>
</Form.Item>
<Test mode="3" name="ding"/>
</Form.Item>
<Form.Item name="qy_wx" label="企业微信">
<Input placeholder="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"/>
<Form.Item label="企业微信">
<Form.Item noStyle name="qy_wx">
<Input placeholder="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"/>
</Form.Item>
<Test mode="5" name="qy_wx"/>
</Form.Item>
</Form>
</Modal>