add metric_view crud method

This commit is contained in:
Ulric Qin 2022-03-27 19:06:31 +08:00
parent 46e2fc6ab6
commit c557e383b6
6 changed files with 181 additions and 14 deletions

View File

@ -296,14 +296,25 @@ 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 `metric_view` (
`id` bigint unsigned not null auto_increment,
`name` varchar(191) not null default '',
`cate` tinyint(1) not null comment '0: preset 1: custom',
`configs` varchar(8192) not null default '',
`create_at` bigint not null default 0,
`create_by` bigint not null default 0 comment 'user id',
`update_at` bigint not null default 0,
PRIMARY KEY (`id`),
KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET = utf8mb4;
CREATE TABLE `alert_aggr_view` ( CREATE TABLE `alert_aggr_view` (
`id` bigint unsigned not null auto_increment, `id` bigint unsigned not null auto_increment,
`name` varchar(191) not null default '', `name` varchar(191) not null default '',
`rule` varchar(2048) not null default '', `rule` varchar(2048) not null default '',
`cate` tinyint(1) not null comment '0: preset 1: custom', `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_at` bigint not null default 0,
`create_by` varchar(64) not null default '', `create_by` bigint not null default 0 comment 'user id',
`update_at` bigint not null default 0, `update_at` bigint not null default 0,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY (`user_id`) KEY (`user_id`)

View File

@ -16,9 +16,8 @@ type AlertAggrView struct {
Name string `json:"name"` Name string `json:"name"`
Rule string `json:"rule"` Rule string `json:"rule"`
Cate int `json:"cate"` Cate int `json:"cate"`
UserId int64 `json:"user_id"`
CreateAt int64 `json:"create_at"` CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"` CreateBy int64 `json:"create_by"`
UpdateAt int64 `json:"update_at"` UpdateAt int64 `json:"update_at"`
} }
@ -49,7 +48,7 @@ func (v *AlertAggrView) Verify() error {
"target_note", "target_note",
} }
arr := strings.Fields(v.Rule) arr := strings.Split(v.Rule, "::")
for i := 0; i < len(arr); i++ { for i := 0; i < len(arr); i++ {
pair := strings.Split(arr[i], ":") pair := strings.Split(arr[i], ":")
if len(pair) != 2 { if len(pair) != 2 {
@ -96,17 +95,17 @@ func (v *AlertAggrView) Update(name, rule string) error {
} }
// AlertAggrViewDel: userid for safe delete // AlertAggrViewDel: userid for safe delete
func AlertAggrViewDel(ids []int64, userId interface{}) error { func AlertAggrViewDel(ids []int64, createBy interface{}) error {
if len(ids) == 0 { if len(ids) == 0 {
return nil return nil
} }
return DB().Where("id in ? and user_id = ?", ids, userId).Delete(new(AlertAggrView)).Error return DB().Where("id in ? and create_by = ?", ids, createBy).Delete(new(AlertAggrView)).Error
} }
func AlertAggrViewGets(userId interface{}) ([]AlertAggrView, error) { func AlertAggrViewGets(createBy interface{}) ([]AlertAggrView, error) {
var lst []AlertAggrView var lst []AlertAggrView
err := DB().Where("user_id = ? or cate = 0", userId).Find(&lst).Error err := DB().Where("create_by = ? or cate = 0", createBy).Find(&lst).Error
if err == nil && len(lst) > 0 { if err == nil && len(lst) > 0 {
sort.Slice(lst, func(i, j int) bool { sort.Slice(lst, func(i, j int) bool {
return lst[i].Name < lst[j].Name return lst[i].Name < lst[j].Name

95
src/models/metric_view.go Normal file
View File

@ -0,0 +1,95 @@
package models
import (
"errors"
"sort"
"strings"
"time"
)
// MetricView 在告警聚合视图查看的时候,要存储一些聚合规则
type MetricView struct {
Id int64 `json:"id" gorm:"primaryKey"`
Name string `json:"name"`
Cate int `json:"cate"`
Configs string `json:"configs"`
CreateAt int64 `json:"create_at"`
CreateBy int64 `json:"create_by"`
UpdateAt int64 `json:"update_at"`
}
func (v *MetricView) TableName() string {
return "metric_view"
}
func (v *MetricView) Verify() error {
v.Name = strings.TrimSpace(v.Name)
if v.Name == "" {
return errors.New("name is blank")
}
v.Configs = strings.TrimSpace(v.Configs)
if v.Configs == "" {
return errors.New("configs is blank")
}
return nil
}
func (v *MetricView) 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 *MetricView) Update(name, configs string) error {
if err := v.Verify(); err != nil {
return err
}
v.UpdateAt = time.Now().Unix()
v.Name = name
v.Configs = configs
return DB().Model(v).Select("name", "configs", "update_at").Updates(v).Error
}
// MetricViewDel: userid for safe delete
func MetricViewDel(ids []int64, createBy interface{}) error {
if len(ids) == 0 {
return nil
}
return DB().Where("id in ? and create_by = ?", ids, createBy).Delete(new(MetricView)).Error
}
func MetricViewGets(createBy interface{}) ([]MetricView, error) {
var lst []MetricView
err := DB().Where("create_by = ? or cate = 0", createBy).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 MetricViewGet(where string, args ...interface{}) (*MetricView, error) {
var lst []*MetricView
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

@ -134,6 +134,11 @@ func configRoute(r *gin.Engine, version string) {
pages.PUT("/user/:id/password", jwtAuth(), admin(), userPasswordPut) pages.PUT("/user/:id/password", jwtAuth(), admin(), userPasswordPut)
pages.DELETE("/user/:id", jwtAuth(), admin(), userDel) pages.DELETE("/user/:id", jwtAuth(), admin(), userDel)
pages.GET("/metric-views", jwtAuth(), metricViewGets)
pages.DELETE("/metric-views", jwtAuth(), metricViewDel)
pages.POST("/metric-views", jwtAuth(), metricViewAdd)
pages.PUT("/metric-views", jwtAuth(), metricViewPut)
pages.GET("/user-groups", jwtAuth(), user(), userGroupGets) pages.GET("/user-groups", jwtAuth(), user(), userGroupGets)
pages.POST("/user-groups", jwtAuth(), user(), perm("/user-groups/add"), userGroupAdd) pages.POST("/user-groups", jwtAuth(), user(), perm("/user-groups/add"), userGroupAdd)
pages.GET("/user-group/:id", jwtAuth(), user(), userGroupGet) pages.GET("/user-group/:id", jwtAuth(), user(), userGroupGet)

View File

@ -8,23 +8,24 @@ import (
"github.com/toolkits/pkg/ginx" "github.com/toolkits/pkg/ginx"
) )
// no param
func alertAggrViewGets(c *gin.Context) { func alertAggrViewGets(c *gin.Context) {
lst, err := models.AlertAggrViewGets(c.MustGet("userid")) lst, err := models.AlertAggrViewGets(c.MustGet("userid"))
ginx.NewRender(c).Data(lst, err) ginx.NewRender(c).Data(lst, err)
} }
// name and rule is necessary // body: name, rule
func alertAggrViewAdd(c *gin.Context) { func alertAggrViewAdd(c *gin.Context) {
var f models.AlertAggrView var f models.AlertAggrView
ginx.BindJSON(c, &f) ginx.BindJSON(c, &f)
f.Id = 0 f.Id = 0
f.CreateBy = c.MustGet("username").(string) f.CreateBy = c.MustGet("userid").(int64)
f.UserId = c.MustGet("userid").(int64)
ginx.NewRender(c).Message(f.Add()) ginx.NewRender(c).Message(f.Add())
} }
// body: ids
func alertAggrViewDel(c *gin.Context) { func alertAggrViewDel(c *gin.Context) {
var f idsForm var f idsForm
ginx.BindJSON(c, &f) ginx.BindJSON(c, &f)
@ -32,7 +33,7 @@ func alertAggrViewDel(c *gin.Context) {
ginx.NewRender(c).Message(models.AlertAggrViewDel(f.Ids, c.MustGet("userid"))) ginx.NewRender(c).Message(models.AlertAggrViewDel(f.Ids, c.MustGet("userid")))
} }
// id / name / rule is necessary // body: id, name, rule
func alertAggrViewPut(c *gin.Context) { func alertAggrViewPut(c *gin.Context) {
var f models.AlertAggrView var f models.AlertAggrView
ginx.BindJSON(c, &f) ginx.BindJSON(c, &f)
@ -46,7 +47,7 @@ func alertAggrViewPut(c *gin.Context) {
} }
userid := c.MustGet("userid").(int64) userid := c.MustGet("userid").(int64)
if view.UserId != userid { if view.CreateBy != userid {
ginx.NewRender(c, http.StatusForbidden).Message("forbidden") ginx.NewRender(c, http.StatusForbidden).Message("forbidden")
return return
} }

View File

@ -0,0 +1,56 @@
package router
import (
"net/http"
"github.com/didi/nightingale/v5/src/models"
"github.com/gin-gonic/gin"
"github.com/toolkits/pkg/ginx"
)
// no param
func metricViewGets(c *gin.Context) {
lst, err := models.MetricViewGets(c.MustGet("userid"))
ginx.NewRender(c).Data(lst, err)
}
// body: name, configs
func metricViewAdd(c *gin.Context) {
var f models.MetricView
ginx.BindJSON(c, &f)
f.Id = 0
f.CreateBy = c.MustGet("userid").(int64)
ginx.NewRender(c).Message(f.Add())
}
// body: ids
func metricViewDel(c *gin.Context) {
var f idsForm
ginx.BindJSON(c, &f)
ginx.NewRender(c).Message(models.MetricViewDel(f.Ids, c.MustGet("userid")))
}
// body: id, name, configs
func metricViewPut(c *gin.Context) {
var f models.MetricView
ginx.BindJSON(c, &f)
view, err := models.MetricViewGet("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.CreateBy != userid {
ginx.NewRender(c, http.StatusForbidden).Message("forbidden")
return
}
ginx.NewRender(c).Message(view.Update(f.Name, f.Configs))
}