Merge branch 'master' of github.com:didi/nightingale
This commit is contained in:
commit
e288a3d3a9
157
http/router.go
157
http/router.go
|
@ -7,19 +7,20 @@ import (
|
|||
"github.com/gin-contrib/gzip"
|
||||
"github.com/gin-contrib/pprof"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/toolkits/csrf"
|
||||
|
||||
"github.com/didi/nightingale/v5/config"
|
||||
)
|
||||
|
||||
func configRoutes(r *gin.Engine) {
|
||||
csrfMid := csrf.Middleware(csrf.Options{
|
||||
Secret: config.Config.HTTP.CsrfSecret,
|
||||
ErrorFunc: func(c *gin.Context) {
|
||||
c.JSON(452, gin.H{"err": "csrf token mismatch"})
|
||||
c.Abort()
|
||||
},
|
||||
})
|
||||
/*
|
||||
csrfMid := csrf.Middleware(csrf.Options{
|
||||
Secret: config.Config.HTTP.CsrfSecret,
|
||||
ErrorFunc: func(c *gin.Context) {
|
||||
c.JSON(452, gin.H{"err": "csrf token mismatch"})
|
||||
c.Abort()
|
||||
},
|
||||
})
|
||||
*/
|
||||
|
||||
if config.Config.HTTP.Pprof {
|
||||
pprof.Register(r, "/api/debug/pprof")
|
||||
|
@ -51,12 +52,14 @@ func configRoutes(r *gin.Engine) {
|
|||
}
|
||||
|
||||
// for brower, expose location in nginx.conf
|
||||
pages := r.Group("/api/n9e", csrfMid)
|
||||
pages := r.Group("/api/n9e")
|
||||
|
||||
{
|
||||
pages.GET("/csrf", func(c *gin.Context) {
|
||||
renderData(c, csrf.GetToken(c), nil)
|
||||
})
|
||||
/*
|
||||
pages.GET("/csrf", func(c *gin.Context) {
|
||||
renderData(c, csrf.GetToken(c), nil)
|
||||
})
|
||||
*/
|
||||
|
||||
pages.GET("/roles", rolesGet)
|
||||
pages.GET("/self/profile", selfProfileGet)
|
||||
|
@ -83,6 +86,8 @@ func configRoutes(r *gin.Engine) {
|
|||
pages.DELETE("/user-group/:id", login(), userGroupDel)
|
||||
|
||||
pages.GET("/classpaths", login(), classpathListGets)
|
||||
pages.GET("/classpaths/tree", login(), classpathListNodeGets)
|
||||
pages.GET("/classpaths/tree-node/:id", login(), classpathListNodeGetsById)
|
||||
pages.POST("/classpaths", login(), classpathAdd)
|
||||
pages.PUT("/classpath/:id", login(), classpathPut)
|
||||
pages.DELETE("/classpath/:id", login(), classpathDel)
|
||||
|
@ -180,7 +185,7 @@ func configRoutes(r *gin.Engine) {
|
|||
}
|
||||
|
||||
// for brower, expose location in nginx.conf
|
||||
pagesV2 := r.Group("/api/n9e/v2", csrfMid)
|
||||
pagesV2 := r.Group("/api/n9e/v2")
|
||||
{
|
||||
pagesV2.POST("/collect-rules", login(), collectRulesAdd)
|
||||
}
|
||||
|
@ -188,135 +193,19 @@ func configRoutes(r *gin.Engine) {
|
|||
// for thirdparty, do not expose location in nginx.conf
|
||||
v1 := r.Group("/v1/n9e")
|
||||
{
|
||||
v1.GET("/roles", rolesGet)
|
||||
v1.GET("/self/profile", selfProfileGet)
|
||||
v1.PUT("/self/profile", selfProfilePut)
|
||||
v1.PUT("/self/password", selfPasswordPut)
|
||||
v1.GET("/self/token", selfTokenGets)
|
||||
v1.POST("/self/token", selfTokenPost)
|
||||
v1.PUT("/self/token", selfTokenPut)
|
||||
v1.GET("/users", login(), userGets)
|
||||
v1.POST("/users", admin(), userAddPost)
|
||||
v1.GET("/user/:id/profile", login(), userProfileGet)
|
||||
v1.PUT("/user/:id/profile", admin(), userProfilePut)
|
||||
v1.PUT("/user/:id/status", admin(), userStatusPut)
|
||||
v1.PUT("/user/:id/password", admin(), userPasswordPut)
|
||||
v1.DELETE("/user/:id", admin(), userDel)
|
||||
|
||||
v1.GET("/user-groups", login(), userGroupListGet)
|
||||
v1.GET("/user-groups/mine", login(), userGroupMineGet)
|
||||
v1.POST("/user-groups", login(), userGroupAdd)
|
||||
v1.PUT("/user-group/:id", login(), userGroupPut)
|
||||
v1.GET("/user-group/:id", login(), userGroupGet)
|
||||
v1.POST("/user-group/:id/members", login(), userGroupMemberAdd)
|
||||
v1.DELETE("/user-group/:id/members", login(), userGroupMemberDel)
|
||||
v1.DELETE("/user-group/:id", login(), userGroupDel)
|
||||
|
||||
v1.GET("/classpaths", login(), classpathListGets)
|
||||
v1.POST("/classpaths", login(), classpathAdd)
|
||||
v1.PUT("/classpath/:id", login(), classpathPut)
|
||||
v1.DELETE("/classpath/:id", login(), classpathDel)
|
||||
v1.POST("/classpath/:id/resources", login(), classpathAddResources)
|
||||
v1.DELETE("/classpath/:id/resources", login(), classpathDelResources)
|
||||
v1.GET("/classpath/:id/resources", login(), classpathGetsResources)
|
||||
|
||||
v1.GET("/classpaths/favorites", login(), classpathFavoriteGet)
|
||||
v1.POST("/classpath/:id/favorites", login(), classpathFavoriteAdd)
|
||||
v1.DELETE("/classpath/:id/favorites", login(), classpathFavoriteDel)
|
||||
|
||||
v1.GET("/resources", login(), resourcesQuery)
|
||||
v1.PUT("/resources/note", resourceNotePut)
|
||||
v1.PUT("/resources/tags", resourceTagsPut)
|
||||
v1.PUT("/resources/classpaths", resourceClasspathsPut)
|
||||
v1.PUT("/resources/mute", resourceMutePut)
|
||||
v1.GET("/resource/:id", login(), resourceGet)
|
||||
v1.DELETE("/resource/:id", login(), resourceDel)
|
||||
|
||||
v1.GET("/classpath/:id/collect-rules", login(), collectRuleGets)
|
||||
|
||||
v1.GET("/mutes", login(), muteGets)
|
||||
v1.POST("/mutes", login(), muteAdd)
|
||||
v1.GET("/mute/:id", login(), muteGet)
|
||||
v1.DELETE("/mute/:id", login(), muteDel)
|
||||
|
||||
v1.GET("/dashboards", login(), dashboardGets)
|
||||
v1.POST("/dashboards", login(), dashboardAdd)
|
||||
v1.GET("/dashboard/:id", login(), dashboardGet)
|
||||
v1.PUT("/dashboard/:id", login(), dashboardPut)
|
||||
v1.DELETE("/dashboard/:id", login(), dashboardDel)
|
||||
v1.POST("/dashboard/:id/favorites", login(), dashboardFavoriteAdd)
|
||||
v1.DELETE("/dashboard/:id/favorites", login(), dashboardFavoriteDel)
|
||||
v1.GET("/dashboard/:id/chart-groups", login(), chartGroupGets)
|
||||
v1.POST("/dashboard/:id/chart-groups", login(), chartGroupAdd)
|
||||
|
||||
v1.PUT("/chart-groups", login(), chartGroupsPut)
|
||||
v1.DELETE("/chart-group/:id", login(), chartGroupDel)
|
||||
v1.GET("/chart-group/:id/charts", login(), chartGets)
|
||||
v1.POST("/chart-group/:id/charts", login(), chartAdd)
|
||||
v1.PUT("/chart/:id", login(), chartPut)
|
||||
v1.DELETE("/chart/:id", login(), chartDel)
|
||||
v1.PUT("/charts/configs", login(), chartConfigsPut)
|
||||
v1.GET("/charts/tmps", login(), chartTmpGets)
|
||||
v1.POST("/charts/tmps", login(), chartTmpAdd)
|
||||
|
||||
v1.GET("/alert-rule-groups", login(), alertRuleGroupGets)
|
||||
v1.POST("/alert-rule-groups", login(), alertRuleGroupAdd)
|
||||
v1.GET("/alert-rule-group/:id", login(), alertRuleGroupGet)
|
||||
v1.PUT("/alert-rule-group/:id", login(), alertRuleGroupPut)
|
||||
v1.DELETE("/alert-rule-group/:id", login(), alertRuleGroupDel)
|
||||
|
||||
v1.GET("/alert-rule-groups/favorites", login(), alertRuleGroupFavoriteGet)
|
||||
v1.DELETE("/alert-rule-group/:id/favorites", login(), alertRuleGroupFavoriteDel)
|
||||
v1.POST("/alert-rule-group/:id/favorites", login(), alertRuleGroupFavoriteAdd)
|
||||
|
||||
v1.GET("/alert-rule-group/:id/alert-rules", login(), alertRuleOfGroupGet)
|
||||
v1.DELETE("/alert-rule-group/:id/alert-rules", login(), alertRuleOfGroupDel)
|
||||
|
||||
v1.POST("/alert-rules", login(), alertRuleAdd)
|
||||
v1.PUT("/alert-rules/status", login(), alertRuleStatusPut)
|
||||
v1.PUT("/alert-rules/notify-groups", login(), alertRuleNotifyGroupsPut)
|
||||
v1.PUT("/alert-rules/notify-channels", login(), alertRuleNotifyChannelsPut)
|
||||
v1.PUT("/alert-rules/append-tags", login(), alertRuleAppendTagsPut)
|
||||
v1.GET("/alert-rule/:id", login(), alertRuleGet)
|
||||
v1.PUT("/alert-rule/:id", login(), alertRulePut)
|
||||
v1.DELETE("/alert-rule/:id", login(), alertRuleDel)
|
||||
|
||||
v1.GET("/alert-events", login(), alertEventGets)
|
||||
v1.DELETE("/alert-events", login(), alertEventsDel)
|
||||
v1.GET("/alert-event/:id", login(), alertEventGet)
|
||||
v1.DELETE("/alert-event/:id", login(), alertEventDel)
|
||||
|
||||
v1.GET("/history-alert-events", login(), historyAlertEventGets)
|
||||
v1.GET("/history-alert-event/:id", login(), historyAlertEventGet)
|
||||
|
||||
v1.POST("/collect-rules", login(), collectRuleAdd)
|
||||
v1.DELETE("/collect-rules", login(), collectRuleDel)
|
||||
v1.PUT("/collect-rule/:id", login(), collectRulePut)
|
||||
v1.GET("/collect-rules-belong-to-ident", collectRuleGetsByIdent)
|
||||
v1.GET("/collect-rules-summary", collectRuleSummaryGetByIdent)
|
||||
|
||||
v1.GET("/metric-descriptions", metricDescriptionGets)
|
||||
v1.POST("/metric-descriptions", login(), metricDescriptionAdd)
|
||||
v1.DELETE("/metric-descriptions", login(), metricDescriptionDel)
|
||||
v1.PUT("/metric-description/:id", login(), metricDescriptionPut)
|
||||
|
||||
v1.GET("/contact-channels", contactChannelsGet)
|
||||
v1.GET("/notify-channels", notifyChannelsGet)
|
||||
|
||||
v1.POST("/push", PushData)
|
||||
|
||||
v1.GET("/status", Status)
|
||||
|
||||
v1.POST("/query", GetData)
|
||||
v1.POST("/instant-query", GetDataInstant)
|
||||
v1.POST("/tag-keys", GetTagKeys)
|
||||
v1.POST("/tag-values", GetTagValues)
|
||||
v1.POST("/tag-metrics", GetMetrics)
|
||||
v1.POST("/tag-pairs", GetTagPairs)
|
||||
v1.GET("/check-promql", checkPromeQl)
|
||||
v1.POST("/tag-metrics", GetMetrics)
|
||||
v1.POST("/push", PushData)
|
||||
v1.GET("/collect-rules-belong-to-ident", collectRuleGetsByIdent)
|
||||
v1.GET("/collect-rules-summary", collectRuleSummaryGetByIdent)
|
||||
|
||||
v1.GET("/can-do-op-by-name", login(), canDoOpByName)
|
||||
v1.GET("/can-do-op-by-token", login(), canDoOpByToken)
|
||||
|
||||
}
|
||||
|
||||
push := r.Group("/v1/n9e/series").Use(gzip.Gzip(gzip.DefaultCompression))
|
||||
|
|
|
@ -24,6 +24,21 @@ func classpathListGets(c *gin.Context) {
|
|||
}, nil)
|
||||
}
|
||||
|
||||
func classpathListNodeGets(c *gin.Context) {
|
||||
query := queryStr(c, "query", "")
|
||||
|
||||
list, err := models.ClasspathNodeGets(query)
|
||||
dangerous(err)
|
||||
|
||||
renderData(c, list, nil)
|
||||
}
|
||||
|
||||
func classpathListNodeGetsById(c *gin.Context) {
|
||||
cp := Classpath(urlParamInt64(c, "id"))
|
||||
children, err := cp.DirectChildren()
|
||||
renderData(c, children, err)
|
||||
}
|
||||
|
||||
func classpathFavoriteGet(c *gin.Context) {
|
||||
lst, err := loginUser(c).FavoriteClasspaths()
|
||||
renderData(c, lst, err)
|
||||
|
|
|
@ -19,6 +19,14 @@ type Classpath struct {
|
|||
UpdateBy string `json:"update_by"`
|
||||
}
|
||||
|
||||
type ClasspathNode struct {
|
||||
Id int64 `json:"id"`
|
||||
Path string `json:"path"`
|
||||
Note string `json:"note"`
|
||||
Preset int `json:"preset"`
|
||||
Children []*ClasspathNode `json:"children"`
|
||||
}
|
||||
|
||||
func (c *Classpath) TableName() string {
|
||||
return "classpath"
|
||||
}
|
||||
|
@ -104,7 +112,6 @@ func ClasspathGets(query string, limit, offset int) ([]Classpath, error) {
|
|||
q := "%" + query + "%"
|
||||
session = session.Where("path like ?", q)
|
||||
}
|
||||
|
||||
var objs []Classpath
|
||||
err := session.Find(&objs)
|
||||
if err != nil {
|
||||
|
@ -151,7 +158,7 @@ func ClasspathGet(where string, args ...interface{}) (*Classpath, error) {
|
|||
|
||||
func ClasspathGetsByPrefix(prefix string) ([]Classpath, error) {
|
||||
var objs []Classpath
|
||||
err := DB.Where("path like ?", prefix+"%").Find(&objs)
|
||||
err := DB.Where("path like ?", prefix+"%").OrderBy("path").Find(&objs)
|
||||
if err != nil {
|
||||
logger.Errorf("mysql.error: query classpath fail: %v", err)
|
||||
return objs, internalServerError
|
||||
|
@ -218,3 +225,94 @@ func (c *Classpath) AddResources(idents []string) error {
|
|||
func (c *Classpath) DelResources(idents []string) error {
|
||||
return ClasspathResourceDel(c.Id, idents)
|
||||
}
|
||||
|
||||
func ClasspathNodeGets(query string) ([]*ClasspathNode, error) {
|
||||
session := DB.OrderBy("path")
|
||||
if query != "" {
|
||||
q := "%" + query + "%"
|
||||
session = session.Where("path like ?", q)
|
||||
}
|
||||
var objs []Classpath
|
||||
err := session.Find(&objs)
|
||||
if err != nil {
|
||||
logger.Errorf("mysql.error: query classpath fail: %v", err)
|
||||
return []*ClasspathNode{}, internalServerError
|
||||
}
|
||||
|
||||
if len(objs) == 0 {
|
||||
return []*ClasspathNode{}, nil
|
||||
}
|
||||
pcs := ClasspathNodeAllChildren(objs)
|
||||
|
||||
return pcs, nil
|
||||
}
|
||||
|
||||
func (cp *Classpath) DirectChildren() ([]Classpath, error) {
|
||||
var pcs []Classpath
|
||||
objs, err := ClasspathGetsByPrefix(cp.Path)
|
||||
if err != nil {
|
||||
logger.Errorf("mysql.error: query prefix classpath fail: %v", err)
|
||||
return []Classpath{}, internalServerError
|
||||
}
|
||||
if len(objs) < 2 {
|
||||
return []Classpath{}, nil
|
||||
}
|
||||
|
||||
pre := objs[1]
|
||||
path := pre.Path[len(objs[0].Path):]
|
||||
pre.Path = path
|
||||
pcs = append(pcs, pre)
|
||||
|
||||
for _, cp := range objs[2:] {
|
||||
has := strings.HasPrefix(cp.Path, pre.Path)
|
||||
if !has {
|
||||
path := cp.Path[len(objs[0].Path):]
|
||||
pre.Path = path
|
||||
pcs = append(pcs, pre)
|
||||
pre = cp
|
||||
}
|
||||
}
|
||||
|
||||
return pcs, nil
|
||||
}
|
||||
|
||||
func ClasspathNodeAllChildren(cps []Classpath) []*ClasspathNode {
|
||||
var node ClasspathNode
|
||||
for _, cp := range cps {
|
||||
ListInsert(cp, &node)
|
||||
}
|
||||
|
||||
return node.Children
|
||||
}
|
||||
|
||||
func ListInsert(obj Classpath, node *ClasspathNode) {
|
||||
path := obj.Path
|
||||
has := true
|
||||
for {
|
||||
if len(node.Children) == 0 {
|
||||
break
|
||||
}
|
||||
children := node.Children[len(node.Children)-1]
|
||||
prefix := children.Path
|
||||
has = strings.HasPrefix(path, prefix)
|
||||
if !has {
|
||||
break
|
||||
}
|
||||
path = path[len(prefix):]
|
||||
node = children
|
||||
}
|
||||
|
||||
newNode := ToClasspathNode(obj, path)
|
||||
node.Children = append(node.Children, &newNode)
|
||||
}
|
||||
|
||||
func ToClasspathNode(cp Classpath, path string) ClasspathNode {
|
||||
var obj ClasspathNode
|
||||
obj.Id = cp.Id
|
||||
obj.Path = path
|
||||
obj.Note = cp.Note
|
||||
obj.Preset = cp.Preset
|
||||
obj.Children = []*ClasspathNode{}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue