mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-02-04 12:40:07 +00:00
add alert api (#458)
This commit is contained in:
177
cmd/dashboard/controller/alertrule.go
Normal file
177
cmd/dashboard/controller/alertrule.go
Normal file
@@ -0,0 +1,177 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jinzhu/copier"
|
||||
|
||||
"github.com/naiba/nezha/model"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
)
|
||||
|
||||
// List Alert rules
|
||||
// @Summary List Alert rules
|
||||
// @Security BearerAuth
|
||||
// @Schemes
|
||||
// @Description List Alert rules
|
||||
// @Tags auth required
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[[]model.AlertRule]
|
||||
// @Router /alert-rule [get]
|
||||
func listAlertRule(c *gin.Context) ([]*model.AlertRule, error) {
|
||||
singleton.AlertsLock.RLock()
|
||||
defer singleton.AlertsLock.RUnlock()
|
||||
|
||||
var ar []*model.AlertRule
|
||||
if err := copier.Copy(&ar, &singleton.Alerts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ar, nil
|
||||
}
|
||||
|
||||
// Add Alert Rule
|
||||
// @Summary Add Alert Rule
|
||||
// @Security BearerAuth
|
||||
// @Schemes
|
||||
// @Description Add Alert Rule
|
||||
// @Tags auth required
|
||||
// @Accept json
|
||||
// @param request body model.AlertRuleForm true "AlertRuleForm"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[uint64]
|
||||
// @Router /alert-rule [post]
|
||||
func createAlertRule(c *gin.Context) (uint64, error) {
|
||||
var arf model.AlertRuleForm
|
||||
var r model.AlertRule
|
||||
|
||||
if err := c.ShouldBindJSON(&arf); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err := validateRule(&r); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r.Name = arf.Name
|
||||
r.Rules = arf.Rules
|
||||
r.FailTriggerTasks = arf.FailTriggerTasks
|
||||
r.RecoverTriggerTasks = arf.RecoverTriggerTasks
|
||||
r.NotificationGroupID = arf.NotificationGroupID
|
||||
enable := arf.Enable
|
||||
r.TriggerMode = arf.TriggerMode
|
||||
r.Enable = &enable
|
||||
r.ID = arf.ID
|
||||
|
||||
if err := singleton.DB.Create(&r).Error; err != nil {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddAlert(r)
|
||||
return r.ID, nil
|
||||
}
|
||||
|
||||
// Update Alert Rule
|
||||
// @Summary Update Alert Rule
|
||||
// @Security BearerAuth
|
||||
// @Schemes
|
||||
// @Description Update Alert Rule
|
||||
// @Tags auth required
|
||||
// @Accept json
|
||||
// @param id path uint true "Alert ID"
|
||||
// @param request body model.AlertRuleForm true "AlertRuleForm"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[any]
|
||||
// @Router /alert-rule/{id} [patch]
|
||||
func updateAlertRule(c *gin.Context) (any, error) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var arf model.AlertRuleForm
|
||||
if err := c.ShouldBindJSON(&arf); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var r model.AlertRule
|
||||
if err := singleton.DB.First(&r, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("alert id %d does not exist", id)
|
||||
}
|
||||
|
||||
if err := validateRule(&r); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r.Name = arf.Name
|
||||
r.Rules = arf.Rules
|
||||
r.FailTriggerTasks = arf.FailTriggerTasks
|
||||
r.RecoverTriggerTasks = arf.RecoverTriggerTasks
|
||||
r.NotificationGroupID = arf.NotificationGroupID
|
||||
enable := arf.Enable
|
||||
r.TriggerMode = arf.TriggerMode
|
||||
r.Enable = &enable
|
||||
r.ID = arf.ID
|
||||
|
||||
if err := singleton.DB.Save(&r).Error; err != nil {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddAlert(r)
|
||||
return r.ID, nil
|
||||
}
|
||||
|
||||
// Batch delete Alert rules
|
||||
// @Summary Batch delete Alert rules
|
||||
// @Security BearerAuth
|
||||
// @Schemes
|
||||
// @Description Batch delete Alert rules
|
||||
// @Tags auth required
|
||||
// @Accept json
|
||||
// @param request body []uint64 true "id list"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[any]
|
||||
// @Router /batch-delete/alert-rule [post]
|
||||
func batchDeleteAlertRule(c *gin.Context) (any, error) {
|
||||
var ar []uint64
|
||||
|
||||
if err := c.ShouldBindJSON(&ar); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := singleton.DB.Unscoped().Delete(&model.DDNSProfile{}, "id in (?)", ar).Error; err != nil {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnDeleteAlert(ar)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func validateRule(r *model.AlertRule) error {
|
||||
if len(r.Rules) > 0 {
|
||||
for _, rule := range r.Rules {
|
||||
if !rule.IsTransferDurationRule() {
|
||||
if rule.Duration < 3 {
|
||||
return errors.New("错误: Duration 至少为 3")
|
||||
}
|
||||
} else {
|
||||
if rule.CycleInterval < 1 {
|
||||
return errors.New("错误: cycle_interval 至少为 1")
|
||||
}
|
||||
if rule.CycleStart == nil {
|
||||
return errors.New("错误: cycle_start 未设置")
|
||||
}
|
||||
if rule.CycleStart.After(time.Now()) {
|
||||
return errors.New("错误: cycle_start 是个未来值")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return errors.New("至少定义一条规则")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -92,6 +92,11 @@ func routers(r *gin.Engine) {
|
||||
auth.PATCH("/notification/:id", commonHandler(updateNotification))
|
||||
auth.POST("/batch-delete/notification", commonHandler(batchDeleteNotification))
|
||||
|
||||
auth.GET("/alert-rule", commonHandler(listAlertRule))
|
||||
auth.POST("/alert-rule", commonHandler(createAlertRule))
|
||||
auth.PATCH("/alert-rule/:id", commonHandler(updateAlertRule))
|
||||
auth.POST("/batch-delete/alert-rule", commonHandler(batchDeleteAlertRule))
|
||||
|
||||
auth.GET("/ddns", commonHandler(listDDNS))
|
||||
auth.GET("/ddns/providers", commonHandler(listProviders))
|
||||
auth.POST("/ddns", commonHandler(createDDNS))
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jinzhu/copier"
|
||||
@@ -66,8 +65,7 @@ func createDDNS(c *gin.Context) (uint64, error) {
|
||||
p.EnableIPv6 = &enableIPv6
|
||||
p.MaxRetries = df.MaxRetries
|
||||
p.Provider = df.Provider
|
||||
p.DomainsRaw = df.DomainsRaw
|
||||
p.Domains = strings.Split(p.DomainsRaw, ",")
|
||||
p.Domains = df.Domains
|
||||
p.AccessID = df.AccessID
|
||||
p.AccessSecret = df.AccessSecret
|
||||
p.WebhookURL = df.WebhookURL
|
||||
@@ -137,8 +135,7 @@ func updateDDNS(c *gin.Context) (any, error) {
|
||||
p.EnableIPv6 = &enableIPv6
|
||||
p.MaxRetries = df.MaxRetries
|
||||
p.Provider = df.Provider
|
||||
p.DomainsRaw = df.DomainsRaw
|
||||
p.Domains = strings.Split(p.DomainsRaw, ",")
|
||||
p.Domains = df.Domains
|
||||
p.AccessID = df.AccessID
|
||||
p.AccessSecret = df.AccessSecret
|
||||
p.WebhookURL = df.WebhookURL
|
||||
|
||||
@@ -75,11 +75,6 @@ func (ma *memberAPI) delete(c *gin.Context) {
|
||||
}
|
||||
delete(singleton.Crons, id)
|
||||
}
|
||||
case "alert-rule":
|
||||
err = singleton.DB.Unscoped().Delete(&model.AlertRule{}, "id = ?", id).Error
|
||||
if err == nil {
|
||||
singleton.OnDeleteAlert(id)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, model.Response{
|
||||
|
||||
Reference in New Issue
Block a user