mirror of https://github.com/openspug/spug
A 添加报警联系人的发送报警测试功能
parent
9a03bccb88
commit
d9d5410852
|
@ -9,4 +9,5 @@ urlpatterns = [
|
||||||
path('alarm/', AlarmView.as_view()),
|
path('alarm/', AlarmView.as_view()),
|
||||||
path('group/', GroupView.as_view()),
|
path('group/', GroupView.as_view()),
|
||||||
path('contact/', ContactView.as_view()),
|
path('contact/', ContactView.as_view()),
|
||||||
|
path('test/', handle_test),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
# Released under the AGPL-3.0 License.
|
# Released under the AGPL-3.0 License.
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
from libs import json_response, JsonParser, Argument, auth
|
from libs import json_response, JsonParser, Argument, auth
|
||||||
|
from libs.spug import Notification
|
||||||
from apps.alarm.models import Alarm, Group, Contact
|
from apps.alarm.models import Alarm, Group, Contact
|
||||||
from apps.monitor.models import Detection
|
from apps.monitor.models import Detection
|
||||||
import json
|
import json
|
||||||
|
@ -87,3 +88,29 @@ class ContactView(View):
|
||||||
return json_response(error=f'报警联系组【{group.name}】包含此联系人,请解除关联后再尝试删除该联系人')
|
return json_response(error=f'报警联系组【{group.name}】包含此联系人,请解除关联后再尝试删除该联系人')
|
||||||
Contact.objects.filter(pk=form.id).delete()
|
Contact.objects.filter(pk=form.id).delete()
|
||||||
return json_response(error=error)
|
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)
|
||||||
|
|
|
@ -27,16 +27,14 @@ def send_login_wx_code(wx_token, code):
|
||||||
|
|
||||||
class Notification:
|
class Notification:
|
||||||
def __init__(self, grp, event, target, title, message, duration):
|
def __init__(self, grp, event, target, title, message, duration):
|
||||||
|
self.grp = grp
|
||||||
self.event = event
|
self.event = event
|
||||||
self.title = title
|
self.title = title
|
||||||
self.target = target
|
self.target = target
|
||||||
self.message = message
|
self.message = message
|
||||||
self.duration = duration
|
self.duration = duration
|
||||||
self.spug_key, self.u_ids = self._parse_args(grp)
|
self.spug_key = AppSetting.get_default('spug_key')
|
||||||
|
self.u_ids = []
|
||||||
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)], [])
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def handle_request(url, data, mode=None):
|
def handle_request(url, data, mode=None):
|
||||||
|
@ -63,7 +61,7 @@ class Notification:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
Notify.make_system_notify('通知发送失败', f'返回数据:{res}')
|
Notify.make_system_notify('通知发送失败', f'返回数据:{res}')
|
||||||
|
|
||||||
def _monitor_by_wx(self, users):
|
def monitor_by_wx(self, users):
|
||||||
if not self.spug_key:
|
if not self.spug_key:
|
||||||
Notify.make_monitor_notify('发送报警信息失败', '未配置报警服务调用凭据,请在系统管理/系统设置/基本设置/调用凭据中配置。')
|
Notify.make_monitor_notify('发送报警信息失败', '未配置报警服务调用凭据,请在系统管理/系统设置/基本设置/调用凭据中配置。')
|
||||||
return
|
return
|
||||||
|
@ -77,7 +75,7 @@ class Notification:
|
||||||
}
|
}
|
||||||
self.handle_request(f'{spug_server}/apis/notify/wx/', data, 'spug')
|
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', {})
|
mail_service = AppSetting.get_default('mail_service', {})
|
||||||
body = [
|
body = [
|
||||||
f'告警名称:{self.title}',
|
f'告警名称:{self.title}',
|
||||||
|
@ -104,7 +102,7 @@ class Notification:
|
||||||
else:
|
else:
|
||||||
Notify.make_monitor_notify('发送报警信息失败', '未配置报警服务调用凭据,请在系统管理/系统设置/报警服务设置中配置。')
|
Notify.make_monitor_notify('发送报警信息失败', '未配置报警服务调用凭据,请在系统管理/系统设置/报警服务设置中配置。')
|
||||||
|
|
||||||
def _monitor_by_dd(self, users):
|
def monitor_by_dd(self, users):
|
||||||
texts = [
|
texts = [
|
||||||
'## %s ## ' % ('监控告警通知' if self.event == '1' else '告警恢复通知'),
|
'## %s ## ' % ('监控告警通知' if self.event == '1' else '告警恢复通知'),
|
||||||
f'**告警名称:** <font color="#{"f90202" if self.event == "1" else "008000"}">{self.title}</font> ',
|
f'**告警名称:** <font color="#{"f90202" if self.event == "1" else "008000"}">{self.title}</font> ',
|
||||||
|
@ -127,7 +125,7 @@ class Notification:
|
||||||
for url in users:
|
for url in users:
|
||||||
self.handle_request(url, data, 'dd')
|
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', '告警恢复通知')
|
color, title = ('warning', '监控告警通知') if self.event == '1' else ('info', '告警恢复通知')
|
||||||
texts = [
|
texts = [
|
||||||
f'## {title}',
|
f'## {title}',
|
||||||
|
@ -148,28 +146,29 @@ class Notification:
|
||||||
self.handle_request(url, data, 'wx')
|
self.handle_request(url, data, 'wx')
|
||||||
|
|
||||||
def dispatch_monitor(self, modes):
|
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:
|
for mode in modes:
|
||||||
if mode == '1':
|
if mode == '1':
|
||||||
users = set(x.wx_token for x in Contact.objects.filter(id__in=self.u_ids, wx_token__isnull=False))
|
users = set(x.wx_token for x in Contact.objects.filter(id__in=self.u_ids, wx_token__isnull=False))
|
||||||
if not users:
|
if not users:
|
||||||
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的微信Token。')
|
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的微信Token。')
|
||||||
continue
|
continue
|
||||||
self._monitor_by_wx(users)
|
self.monitor_by_wx(users)
|
||||||
elif mode == '3':
|
elif mode == '3':
|
||||||
users = set(x.ding for x in Contact.objects.filter(id__in=self.u_ids, ding__isnull=False))
|
users = set(x.ding for x in Contact.objects.filter(id__in=self.u_ids, ding__isnull=False))
|
||||||
if not users:
|
if not users:
|
||||||
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的钉钉。')
|
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的钉钉。')
|
||||||
continue
|
continue
|
||||||
self._monitor_by_dd(users)
|
self.monitor_by_dd(users)
|
||||||
elif mode == '4':
|
elif mode == '4':
|
||||||
users = set(x.email for x in Contact.objects.filter(id__in=self.u_ids, email__isnull=False))
|
users = set(x.email for x in Contact.objects.filter(id__in=self.u_ids, email__isnull=False))
|
||||||
if not users:
|
if not users:
|
||||||
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的邮件地址。')
|
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的邮件地址。')
|
||||||
continue
|
continue
|
||||||
self._monitor_by_email(users)
|
self.monitor_by_email(users)
|
||||||
elif mode == '5':
|
elif mode == '5':
|
||||||
users = set(x.qy_wx for x in Contact.objects.filter(id__in=self.u_ids, qy_wx__isnull=False))
|
users = set(x.qy_wx for x in Contact.objects.filter(id__in=self.u_ids, qy_wx__isnull=False))
|
||||||
if not users:
|
if not users:
|
||||||
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的企业微信。')
|
Notify.make_monitor_notify('发送报警信息失败', '未找到可用的通知对象,请确保设置了相关报警联系人的企业微信。')
|
||||||
continue
|
continue
|
||||||
self._monitor_by_qy_wx(users)
|
self.monitor_by_qy_wx(users)
|
||||||
|
|
|
@ -5,13 +5,15 @@
|
||||||
*/
|
*/
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { observer } from 'mobx-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 http from 'libs/http';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
export default observer(function () {
|
export default observer(function () {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [testLoading, setTestLoading] = useState('0');
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
@ -25,6 +27,34 @@ export default observer(function () {
|
||||||
}, () => setLoading(false))
|
}, () => 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 (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
visible
|
visible
|
||||||
|
@ -41,23 +71,35 @@ export default observer(function () {
|
||||||
<Form.Item name="phone" label="手机号">
|
<Form.Item name="phone" label="手机号">
|
||||||
<Input placeholder="请输入手机号"/>
|
<Input placeholder="请输入手机号"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="email" label="邮箱">
|
<Form.Item label="邮箱">
|
||||||
<Input placeholder="请输入邮箱地址"/>
|
<Form.Item noStyle name="email">
|
||||||
|
<Input placeholder="请输入邮箱地址"/>
|
||||||
|
</Form.Item>
|
||||||
|
<Test mode="4" name="email"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="wx_token" label="微信Token" extra={
|
<Form.Item label="微信Token" extra={
|
||||||
<a target="_blank" rel="noopener noreferrer"
|
<a target="_blank" rel="noopener noreferrer"
|
||||||
href="https://spug.cc/docs/alarm-contact/">如何获取微信 Token ?</a>}>
|
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>
|
||||||
<Form.Item name="ding" label="钉钉" extra={<span>
|
<Form.Item label="钉钉" extra={<span>
|
||||||
钉钉收不到通知?请参考
|
钉钉收不到通知?请参考
|
||||||
<a target="_blank" rel="noopener noreferrer"
|
<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>
|
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>}>
|
</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>
|
||||||
<Form.Item name="qy_wx" label="企业微信">
|
<Form.Item label="企业微信">
|
||||||
<Input placeholder="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"/>
|
<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.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
Loading…
Reference in New Issue