add alert_aggr_view crud

This commit is contained in:
Ulric Qin 2022-03-22 11:19:06 +08:00
parent d45fdd50e7
commit 025c5809be
7 changed files with 236 additions and 67 deletions

View File

@ -296,6 +296,22 @@ CREATE TABLE `target` (
-- KEY (`group_id`, `type`, `name`)
-- ) 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` (
`id` bigint unsigned not null comment 'use alert_his_event.id',
`cluster` varchar(128) not null,

View File

@ -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
}

View File

@ -217,6 +217,11 @@ func configRoute(r *gin.Engine, version string) {
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.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)

View File

@ -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))
}

View File

@ -1,79 +1,79 @@
package router
import (
"net/http"
// import (
// "net/http"
"github.com/gin-gonic/gin"
"github.com/toolkits/pkg/ginx"
// "github.com/gin-gonic/gin"
// "github.com/toolkits/pkg/ginx"
"github.com/didi/nightingale/v5/src/models"
)
// "github.com/didi/nightingale/v5/src/models"
// )
func collectRuleGets(c *gin.Context) {
busiGroupId := ginx.UrlParamInt64(c, "id")
crs, err := models.CollectRuleGets(busiGroupId, ginx.QueryStr(c, "type", ""))
ginx.NewRender(c).Data(crs, err)
}
// func collectRuleGets(c *gin.Context) {
// busiGroupId := ginx.UrlParamInt64(c, "id")
// crs, err := models.CollectRuleGets(busiGroupId, ginx.QueryStr(c, "type", ""))
// ginx.NewRender(c).Data(crs, err)
// }
func collectRuleAdd(c *gin.Context) {
var lst []models.CollectRule
ginx.BindJSON(c, &lst)
// func collectRuleAdd(c *gin.Context) {
// var lst []models.CollectRule
// ginx.BindJSON(c, &lst)
count := len(lst)
if count == 0 {
ginx.Bomb(http.StatusBadRequest, "input json is empty")
}
// count := len(lst)
// if count == 0 {
// ginx.Bomb(http.StatusBadRequest, "input json is empty")
// }
username := c.MustGet("username").(string)
bgid := ginx.UrlParamInt64(c, "id")
// username := c.MustGet("username").(string)
// bgid := ginx.UrlParamInt64(c, "id")
// collect rule name -> error string
reterr := make(map[string]string)
for i := 0; i < count; i++ {
lst[i].Id = 0
lst[i].GroupId = bgid
lst[i].CreateBy = username
lst[i].UpdateBy = username
lst[i].FE2DB()
// // collect rule name -> error string
// reterr := make(map[string]string)
// for i := 0; i < count; i++ {
// lst[i].Id = 0
// lst[i].GroupId = bgid
// lst[i].CreateBy = username
// lst[i].UpdateBy = username
// lst[i].FE2DB()
if err := lst[i].Add(); err != nil {
reterr[lst[i].Name] = err.Error()
} else {
reterr[lst[i].Name] = ""
}
}
// if err := lst[i].Add(); err != nil {
// reterr[lst[i].Name] = err.Error()
// } else {
// reterr[lst[i].Name] = ""
// }
// }
ginx.NewRender(c).Data(reterr, nil)
}
// ginx.NewRender(c).Data(reterr, nil)
// }
func collectRuleDel(c *gin.Context) {
var f idsForm
ginx.BindJSON(c, &f)
f.Verify()
// func collectRuleDel(c *gin.Context) {
// var f idsForm
// ginx.BindJSON(c, &f)
// f.Verify()
// param(busiGroupId) for protect
ginx.NewRender(c).Message(models.CollectRuleDels(f.Ids, ginx.UrlParamInt64(c, "id")))
}
// // param(busiGroupId) for protect
// ginx.NewRender(c).Message(models.CollectRuleDels(f.Ids, ginx.UrlParamInt64(c, "id")))
// }
func collectRuleGet(c *gin.Context) {
crid := ginx.UrlParamInt64(c, "crid")
cr, err := models.CollectRuleGetById(crid)
ginx.NewRender(c).Data(cr, err)
}
// func collectRuleGet(c *gin.Context) {
// crid := ginx.UrlParamInt64(c, "crid")
// cr, err := models.CollectRuleGetById(crid)
// ginx.NewRender(c).Data(cr, err)
// }
func collectRulePut(c *gin.Context) {
var f models.CollectRule
ginx.BindJSON(c, &f)
// func collectRulePut(c *gin.Context) {
// var f models.CollectRule
// ginx.BindJSON(c, &f)
crid := ginx.UrlParamInt64(c, "crid")
cr, err := models.CollectRuleGetById(crid)
ginx.Dangerous(err)
// crid := ginx.UrlParamInt64(c, "crid")
// cr, err := models.CollectRuleGetById(crid)
// ginx.Dangerous(err)
if cr == nil {
ginx.NewRender(c, http.StatusNotFound).Message("No such CollectRule")
return
}
// if cr == nil {
// ginx.NewRender(c, http.StatusNotFound).Message("No such CollectRule")
// return
// }
f.UpdateBy = c.MustGet("username").(string)
ginx.NewRender(c).Message(cr.Update(f))
}
// f.UpdateBy = c.MustGet("username").(string)
// ginx.NewRender(c).Message(cr.Update(f))
// }

View File

@ -223,10 +223,6 @@ func dashboardImport(c *gin.Context) {
ginx.NewRender(c).Data(ret, nil)
}
type idForm struct {
Id int64 `json:"id" binding:"required"`
}
func dashboardClone(c *gin.Context) {
dash := Dashboard(ginx.UrlParamInt64(c, "did"))
user := c.MustGet("user").(*models.User)

View File

@ -45,7 +45,7 @@ func taskTplGet(c *gin.Context) {
ginx.NewRender(c).Data(gin.H{
"tpl": tpl,
"hosts": hosts,
}, nil)
}, err)
}
type taskTplForm struct {
@ -97,7 +97,8 @@ func taskTplPut(c *gin.Context) {
ginx.Dangerous(err)
if tpl == nil {
ginx.Dangerous("no such task template")
ginx.NewRender(c).Message("no such task template")
return
}
user := c.MustGet("user").(*models.User)