add alert_aggr_view crud
This commit is contained in:
parent
d45fdd50e7
commit
025c5809be
|
@ -296,6 +296,22 @@ CREATE TABLE `target` (
|
||||||
-- KEY (`group_id`, `type`, `name`)
|
-- KEY (`group_id`, `type`, `name`)
|
||||||
-- ) ENGINE=InnoDB DEFAULT CHARSET = utf8mb4;
|
-- ) ENGINE=InnoDB DEFAULT CHARSET = utf8mb4;
|
||||||
|
|
||||||
|
CREATE TABLE `alert_aggr_view` (
|
||||||
|
`id` bigint unsigned not null auto_increment,
|
||||||
|
`name` varchar(191) not null default '',
|
||||||
|
`rule` varchar(2048) not null default '',
|
||||||
|
`cate` tinyint(1) not null comment '0: preset 1: custom',
|
||||||
|
`user_id` bigint not null default 0,
|
||||||
|
`create_at` bigint not null default 0,
|
||||||
|
`create_by` varchar(64) not null default '',
|
||||||
|
`update_at` bigint not null default 0,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY (`user_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET = utf8mb4;
|
||||||
|
|
||||||
|
insert into alert_aggr_view(name, rule, cate) values('GroupBy BusiGroup, Severity', 'field:group_name field:severity', 0);
|
||||||
|
insert into alert_aggr_view(name, rule, cate) values('GroupBy Metric', 'tagkey:__name__', 0);
|
||||||
|
|
||||||
CREATE TABLE `alert_cur_event` (
|
CREATE TABLE `alert_cur_event` (
|
||||||
`id` bigint unsigned not null comment 'use alert_his_event.id',
|
`id` bigint unsigned not null comment 'use alert_his_event.id',
|
||||||
`cluster` varchar(128) not null,
|
`cluster` varchar(128) not null,
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AlertAggrView 在告警聚合视图查看的时候,要存储一些聚合规则
|
||||||
|
type AlertAggrView struct {
|
||||||
|
Id int64 `json:"id" gorm:"primaryKey"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Rule string `json:"rule"`
|
||||||
|
Cate int `json:"cate"`
|
||||||
|
UserId int64 `json:"user_id"`
|
||||||
|
CreateAt int64 `json:"create_at"`
|
||||||
|
CreateBy string `json:"create_by"`
|
||||||
|
UpdateAt int64 `json:"update_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *AlertAggrView) TableName() string {
|
||||||
|
return "alert_aggr_view"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *AlertAggrView) Verify() error {
|
||||||
|
v.Name = strings.TrimSpace(v.Name)
|
||||||
|
if v.Name == "" {
|
||||||
|
return errors.New("name is blank")
|
||||||
|
}
|
||||||
|
|
||||||
|
v.Rule = strings.TrimSpace(v.Rule)
|
||||||
|
if v.Rule == "" {
|
||||||
|
return errors.New("rule is blank")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *AlertAggrView) Add() error {
|
||||||
|
if err := v.Verify(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().Unix()
|
||||||
|
v.CreateAt = now
|
||||||
|
v.UpdateAt = now
|
||||||
|
v.Cate = 1
|
||||||
|
return Insert(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *AlertAggrView) Update(name, rule string) error {
|
||||||
|
if err := v.Verify(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
v.UpdateAt = time.Now().Unix()
|
||||||
|
v.Name = name
|
||||||
|
v.Rule = rule
|
||||||
|
|
||||||
|
return DB().Model(v).Select("name", "rule", "update_at").Updates(v).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// AlertAggrViewDel: userid for safe delete
|
||||||
|
func AlertAggrViewDel(ids []int64, userId interface{}) error {
|
||||||
|
if len(ids) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return DB().Where("id in ? and user_id = ?", ids, userId).Delete(new(AlertAggrView)).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func AlertAggrViewGets(userId interface{}) ([]AlertAggrView, error) {
|
||||||
|
var lst []AlertAggrView
|
||||||
|
err := DB().Where("user_id = ? or cate = 0", userId).Find(&lst).Error
|
||||||
|
if err == nil && len(lst) > 0 {
|
||||||
|
sort.Slice(lst, func(i, j int) bool {
|
||||||
|
return lst[i].Name < lst[j].Name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return lst, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func AlertAggrViewGet(where string, args ...interface{}) (*AlertAggrView, error) {
|
||||||
|
var lst []*AlertAggrView
|
||||||
|
err := DB().Where(where, args...).Find(&lst).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(lst) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return lst[0], nil
|
||||||
|
}
|
|
@ -217,6 +217,11 @@ func configRoute(r *gin.Engine, version string) {
|
||||||
pages.GET("/alert-his-event/:eid", jwtAuth(), alertHisEventGet)
|
pages.GET("/alert-his-event/:eid", jwtAuth(), alertHisEventGet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pages.GET("/alert-aggr-views", jwtAuth(), alertAggrViewGets)
|
||||||
|
pages.DELETE("/alert-aggr-views", jwtAuth(), alertAggrViewDel)
|
||||||
|
pages.POST("/alert-aggr-views", jwtAuth(), alertAggrViewAdd)
|
||||||
|
pages.PUT("/alert-aggr-views", jwtAuth(), alertAggrViewPut)
|
||||||
|
|
||||||
pages.GET("/busi-group/:id/task-tpls", jwtAuth(), user(), perm("/job-tpls"), bgro(), taskTplGets)
|
pages.GET("/busi-group/:id/task-tpls", jwtAuth(), user(), perm("/job-tpls"), bgro(), taskTplGets)
|
||||||
pages.POST("/busi-group/:id/task-tpls", jwtAuth(), user(), perm("/job-tpls/add"), bgrw(), taskTplAdd)
|
pages.POST("/busi-group/:id/task-tpls", jwtAuth(), user(), perm("/job-tpls/add"), bgrw(), taskTplAdd)
|
||||||
pages.DELETE("/busi-group/:id/task-tpl/:tid", jwtAuth(), user(), perm("/job-tpls/del"), bgrw(), taskTplDel)
|
pages.DELETE("/busi-group/:id/task-tpl/:tid", jwtAuth(), user(), perm("/job-tpls/del"), bgrw(), taskTplDel)
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/didi/nightingale/v5/src/models"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/toolkits/pkg/ginx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func alertAggrViewGets(c *gin.Context) {
|
||||||
|
lst, err := models.AlertAggrViewGets(c.MustGet("userid"))
|
||||||
|
ginx.NewRender(c).Data(lst, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// name and rule is necessary
|
||||||
|
func alertAggrViewAdd(c *gin.Context) {
|
||||||
|
var f models.AlertAggrView
|
||||||
|
ginx.BindJSON(c, &f)
|
||||||
|
|
||||||
|
f.Id = 0
|
||||||
|
f.CreateBy = c.MustGet("username").(string)
|
||||||
|
f.UserId = c.MustGet("userid").(int64)
|
||||||
|
|
||||||
|
ginx.NewRender(c).Message(f.Add())
|
||||||
|
}
|
||||||
|
|
||||||
|
func alertAggrViewDel(c *gin.Context) {
|
||||||
|
var f idsForm
|
||||||
|
ginx.BindJSON(c, &f)
|
||||||
|
|
||||||
|
ginx.NewRender(c).Message(models.AlertAggrViewDel(f.Ids, c.MustGet("userid")))
|
||||||
|
}
|
||||||
|
|
||||||
|
// id / name / rule is necessary
|
||||||
|
func alertAggrViewPut(c *gin.Context) {
|
||||||
|
var f models.AlertAggrView
|
||||||
|
ginx.BindJSON(c, &f)
|
||||||
|
|
||||||
|
view, err := models.AlertAggrViewGet("id = ?", f.Id)
|
||||||
|
ginx.Dangerous(err)
|
||||||
|
|
||||||
|
if view == nil {
|
||||||
|
ginx.NewRender(c).Message("no such item(id: %d)", f.Id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userid := c.MustGet("userid").(int64)
|
||||||
|
if view.UserId != userid {
|
||||||
|
ginx.NewRender(c, http.StatusForbidden).Message("forbidden")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ginx.NewRender(c).Message(view.Update(f.Name, f.Rule))
|
||||||
|
}
|
|
@ -1,79 +1,79 @@
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
// import (
|
||||||
"net/http"
|
// "net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
// "github.com/gin-gonic/gin"
|
||||||
"github.com/toolkits/pkg/ginx"
|
// "github.com/toolkits/pkg/ginx"
|
||||||
|
|
||||||
"github.com/didi/nightingale/v5/src/models"
|
// "github.com/didi/nightingale/v5/src/models"
|
||||||
)
|
// )
|
||||||
|
|
||||||
func collectRuleGets(c *gin.Context) {
|
// func collectRuleGets(c *gin.Context) {
|
||||||
busiGroupId := ginx.UrlParamInt64(c, "id")
|
// busiGroupId := ginx.UrlParamInt64(c, "id")
|
||||||
crs, err := models.CollectRuleGets(busiGroupId, ginx.QueryStr(c, "type", ""))
|
// crs, err := models.CollectRuleGets(busiGroupId, ginx.QueryStr(c, "type", ""))
|
||||||
ginx.NewRender(c).Data(crs, err)
|
// ginx.NewRender(c).Data(crs, err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func collectRuleAdd(c *gin.Context) {
|
// func collectRuleAdd(c *gin.Context) {
|
||||||
var lst []models.CollectRule
|
// var lst []models.CollectRule
|
||||||
ginx.BindJSON(c, &lst)
|
// ginx.BindJSON(c, &lst)
|
||||||
|
|
||||||
count := len(lst)
|
// count := len(lst)
|
||||||
if count == 0 {
|
// if count == 0 {
|
||||||
ginx.Bomb(http.StatusBadRequest, "input json is empty")
|
// ginx.Bomb(http.StatusBadRequest, "input json is empty")
|
||||||
}
|
// }
|
||||||
|
|
||||||
username := c.MustGet("username").(string)
|
// username := c.MustGet("username").(string)
|
||||||
bgid := ginx.UrlParamInt64(c, "id")
|
// bgid := ginx.UrlParamInt64(c, "id")
|
||||||
|
|
||||||
// collect rule name -> error string
|
// // collect rule name -> error string
|
||||||
reterr := make(map[string]string)
|
// reterr := make(map[string]string)
|
||||||
for i := 0; i < count; i++ {
|
// for i := 0; i < count; i++ {
|
||||||
lst[i].Id = 0
|
// lst[i].Id = 0
|
||||||
lst[i].GroupId = bgid
|
// lst[i].GroupId = bgid
|
||||||
lst[i].CreateBy = username
|
// lst[i].CreateBy = username
|
||||||
lst[i].UpdateBy = username
|
// lst[i].UpdateBy = username
|
||||||
lst[i].FE2DB()
|
// lst[i].FE2DB()
|
||||||
|
|
||||||
if err := lst[i].Add(); err != nil {
|
// if err := lst[i].Add(); err != nil {
|
||||||
reterr[lst[i].Name] = err.Error()
|
// reterr[lst[i].Name] = err.Error()
|
||||||
} else {
|
// } else {
|
||||||
reterr[lst[i].Name] = ""
|
// reterr[lst[i].Name] = ""
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
ginx.NewRender(c).Data(reterr, nil)
|
// ginx.NewRender(c).Data(reterr, nil)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func collectRuleDel(c *gin.Context) {
|
// func collectRuleDel(c *gin.Context) {
|
||||||
var f idsForm
|
// var f idsForm
|
||||||
ginx.BindJSON(c, &f)
|
// ginx.BindJSON(c, &f)
|
||||||
f.Verify()
|
// f.Verify()
|
||||||
|
|
||||||
// param(busiGroupId) for protect
|
// // param(busiGroupId) for protect
|
||||||
ginx.NewRender(c).Message(models.CollectRuleDels(f.Ids, ginx.UrlParamInt64(c, "id")))
|
// ginx.NewRender(c).Message(models.CollectRuleDels(f.Ids, ginx.UrlParamInt64(c, "id")))
|
||||||
}
|
// }
|
||||||
|
|
||||||
func collectRuleGet(c *gin.Context) {
|
// func collectRuleGet(c *gin.Context) {
|
||||||
crid := ginx.UrlParamInt64(c, "crid")
|
// crid := ginx.UrlParamInt64(c, "crid")
|
||||||
cr, err := models.CollectRuleGetById(crid)
|
// cr, err := models.CollectRuleGetById(crid)
|
||||||
ginx.NewRender(c).Data(cr, err)
|
// ginx.NewRender(c).Data(cr, err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func collectRulePut(c *gin.Context) {
|
// func collectRulePut(c *gin.Context) {
|
||||||
var f models.CollectRule
|
// var f models.CollectRule
|
||||||
ginx.BindJSON(c, &f)
|
// ginx.BindJSON(c, &f)
|
||||||
|
|
||||||
crid := ginx.UrlParamInt64(c, "crid")
|
// crid := ginx.UrlParamInt64(c, "crid")
|
||||||
cr, err := models.CollectRuleGetById(crid)
|
// cr, err := models.CollectRuleGetById(crid)
|
||||||
ginx.Dangerous(err)
|
// ginx.Dangerous(err)
|
||||||
|
|
||||||
if cr == nil {
|
// if cr == nil {
|
||||||
ginx.NewRender(c, http.StatusNotFound).Message("No such CollectRule")
|
// ginx.NewRender(c, http.StatusNotFound).Message("No such CollectRule")
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
f.UpdateBy = c.MustGet("username").(string)
|
// f.UpdateBy = c.MustGet("username").(string)
|
||||||
ginx.NewRender(c).Message(cr.Update(f))
|
// ginx.NewRender(c).Message(cr.Update(f))
|
||||||
}
|
// }
|
||||||
|
|
|
@ -223,10 +223,6 @@ func dashboardImport(c *gin.Context) {
|
||||||
ginx.NewRender(c).Data(ret, nil)
|
ginx.NewRender(c).Data(ret, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
type idForm struct {
|
|
||||||
Id int64 `json:"id" binding:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func dashboardClone(c *gin.Context) {
|
func dashboardClone(c *gin.Context) {
|
||||||
dash := Dashboard(ginx.UrlParamInt64(c, "did"))
|
dash := Dashboard(ginx.UrlParamInt64(c, "did"))
|
||||||
user := c.MustGet("user").(*models.User)
|
user := c.MustGet("user").(*models.User)
|
||||||
|
|
|
@ -45,7 +45,7 @@ func taskTplGet(c *gin.Context) {
|
||||||
ginx.NewRender(c).Data(gin.H{
|
ginx.NewRender(c).Data(gin.H{
|
||||||
"tpl": tpl,
|
"tpl": tpl,
|
||||||
"hosts": hosts,
|
"hosts": hosts,
|
||||||
}, nil)
|
}, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
type taskTplForm struct {
|
type taskTplForm struct {
|
||||||
|
@ -97,7 +97,8 @@ func taskTplPut(c *gin.Context) {
|
||||||
ginx.Dangerous(err)
|
ginx.Dangerous(err)
|
||||||
|
|
||||||
if tpl == nil {
|
if tpl == nil {
|
||||||
ginx.Dangerous("no such task template")
|
ginx.NewRender(c).Message("no such task template")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user := c.MustGet("user").(*models.User)
|
user := c.MustGet("user").(*models.User)
|
||||||
|
|
Loading…
Reference in New Issue