Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"app.go",
"canal.go",
"dapper.go",
"databus.go",
"discovery.go",
"ecode.go",
"http.go",
"monitor.go",
"need.go",
"open.go",
"platform.go",
"pprof.go",
"rank.go",
"upload.go",
"user.go",
"ut.go",
"ut_app.go",
"ut_dash.go",
],
importpath = "go-common/app/admin/main/apm/http",
tags = ["automanaged"],
deps = [
"//app/admin/main/apm/conf:go_default_library",
"//app/admin/main/apm/model/app:go_default_library",
"//app/admin/main/apm/model/canal:go_default_library",
"//app/admin/main/apm/model/databus:go_default_library",
"//app/admin/main/apm/model/ecode:go_default_library",
"//app/admin/main/apm/model/need:go_default_library",
"//app/admin/main/apm/model/pprof:go_default_library",
"//app/admin/main/apm/model/user:go_default_library",
"//app/admin/main/apm/model/ut:go_default_library",
"//app/admin/main/apm/service:go_default_library",
"//app/tool/saga/model:go_default_library",
"//library/conf/env:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/binding:go_default_library",
"//library/net/http/blademaster/middleware/permit:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = [
"apply_test.go",
"canal_test.go",
"ecode_test.go",
"need_test.go",
"notify_test.go",
"process_test.go",
"upload_test.go",
"user_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/apm/conf:go_default_library",
"//app/admin/main/apm/model/canal:go_default_library",
"//app/admin/main/apm/model/need:go_default_library",
"//app/admin/main/apm/service:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,425 @@
package http
import (
"fmt"
"go-common/app/admin/main/apm/model/app"
"go-common/library/ecode"
"go-common/library/log"
"strconv"
"strings"
bm "go-common/library/net/http/blademaster"
)
func appList(c *bm.Context) {
var err error
v := new(struct {
AppID string `form:"app_id"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
})
if err = c.Bind(v); err != nil {
return
}
var (
aa []*app.App
count int
lk = "%" + v.AppID + "%"
)
if v.AppID != "" {
err = apmSvc.DB.Where("app_id LIKE ?", lk).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
} else {
err = apmSvc.DB.Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
}
if err != nil {
log.Error("apmSvc.AppList error(%v)", err)
c.JSON(nil, err)
return
}
if v.AppID != "" {
err = apmSvc.DB.Where("app_id LIKE ?", lk).Model(&app.App{}).Count(&count).Error
} else {
err = apmSvc.DB.Model(&app.App{}).Count(&count).Error
}
if err != nil {
log.Error("apmSvc.AppList count error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: aa,
Total: count,
}
c.JSON(data, nil)
}
func appAdd(c *bm.Context) {
var err error
username := name(c)
v := new(struct {
AppTreeID int64 `form:"app_tree_id" validate:"required"`
AppID string `form:"app_id" validate:"required"`
Limit int64 `form:"limit"`
})
if err = c.Bind(v); err != nil {
return
}
if err = apmSvc.AppAdd(c, username, v.AppTreeID, v.AppID, v.Limit); err != nil {
log.Error("apmSvc.appAdd error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
func appEdit(c *bm.Context) {
var err error
v := new(struct {
ID int `form:"id" validate:"required"`
Limit int `form:"limit" validate:"required"`
})
if err = c.Bind(v); err != nil {
return
}
a := &app.App{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(a).Error; err != nil {
log.Error("apmSvc.appEdit find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
ups := map[string]interface{}{
"limit": v.Limit,
}
if err = apmSvc.DB.Model(&app.App{}).Where("id = ?", v.ID).Updates(ups).Error; err != nil {
log.Error("apmSvc.appEdit updates error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": v.ID,
"Update": ups,
"Old": a,
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 2, int64(v.ID), "apmSvc.appEdit", sqlLog)
c.JSON(nil, err)
}
func appDelete(c *bm.Context) {
v := new(struct {
ID int `form:"id" validate:"required"`
})
username := name(c)
var err error
if err = c.Bind(v); err != nil {
return
}
a := &app.App{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(a).Error; err != nil {
log.Error("apmSvc.appDelete find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Delete(a).Error; err != nil {
log.Error("apmSvc.appDelete delete(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
apmSvc.SendLog(*c, username, 0, 3, int64(v.ID), "apmSvc.appDelete", a)
c.JSON(nil, err)
}
func appAuthList(c *bm.Context) {
v := new(struct {
AppID string `form:"app_id"`
ServiceID string `form:"service_id"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var (
aa []*app.Auth
count int
)
if v.AppID != "" && v.ServiceID != "" {
err = apmSvc.DB.Where("app_id=? and service_id=?", v.AppID, v.ServiceID).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
} else if v.AppID != "" {
err = apmSvc.DB.Where("app_id=?", v.AppID).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
} else if v.ServiceID != "" {
err = apmSvc.DB.Where("service_id=?", v.ServiceID).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
} else {
err = apmSvc.DB.Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
}
if err != nil {
log.Error("apmSvc.appAuthList error(%v)", err)
c.JSON(nil, err)
return
}
if v.AppID != "" {
err = apmSvc.DB.Where("app_id=?", v.AppID).Model(&app.Auth{}).Count(&count).Error
} else {
err = apmSvc.DB.Model(&app.Auth{}).Count(&count).Error
}
if err != nil {
log.Error("apmSvc.appAuthList count error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: aa,
Total: count,
}
c.JSON(data, nil)
}
func appAuthAdd(c *bm.Context) {
v := new(struct {
AppTreeID int64 `form:"app_tree_id" validate:"required"`
AppID string `form:"app_id" validate:"required"`
ServiceTreeID int64 `form:"service_tree_id" validate:"required"`
ServiceID string `form:"service_id" validate:"required"`
RPCMethod string `form:"rpc_method"`
HTTPMethod string `form:"http_method"`
Quota int64 `form:"quota"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
if v.ServiceTreeID == v.AppTreeID {
log.Error("apmSvc.appAuthAdd service_tree_id=app_tree_id error(%v)", v.ServiceTreeID)
c.JSON(nil, ecode.RequestErr)
return
}
cnt := 0
if err = apmSvc.DB.Model(&app.Auth{}).Where("service_tree_id=? and app_tree_id=?", v.ServiceTreeID, v.AppTreeID).Count(&cnt).Error; err != nil {
log.Error("apmSvc.appAuthAdd count error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
if cnt > 0 {
log.Error("apmSvc.appAuthAdd count (%v)", cnt)
c.JSON(nil, ecode.RequestErr)
return
}
a := &app.Auth{
AppTreeID: v.AppTreeID,
AppID: v.AppID,
ServiceTreeID: v.ServiceTreeID,
ServiceID: v.ServiceID,
RPCMethod: v.RPCMethod,
HTTPMethod: v.HTTPMethod,
Quota: v.Quota,
}
if err = apmSvc.DB.Create(a).Error; err != nil {
log.Error("apmSvc.appAuthAdd create error(%v)", err)
c.JSON(nil, err)
return
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 1, a.ID, "apmSvc.appAuthAdd", a)
c.JSON(nil, err)
}
func appAuthEdit(c *bm.Context) {
v := new(struct {
ID int `form:"id" validate:"required"`
RPCMethod string `form:"rpc_method"`
HTTPMethod string `form:"http_method"`
Quota int `form:"quota" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
a := &app.Auth{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(a).Error; err != nil {
log.Error("apmSvc.appAuthEdit find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
ups := map[string]interface{}{
"rpc_method": v.RPCMethod,
"http_method": v.HTTPMethod,
"quota": v.Quota,
}
if err = apmSvc.DB.Model(&app.Auth{}).Where("id = ?", v.ID).Updates(ups).Error; err != nil {
log.Error("apmSvc.appAuthEdit updates error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": v.ID,
"Update": ups,
"Old": a,
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 2, int64(v.ID), "apmSvc.appAuthEdit", sqlLog)
c.JSON(nil, err)
}
func appAuthDelete(c *bm.Context) {
v := new(struct {
ID int `form:"id" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
a := &app.Auth{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(a).Error; err != nil {
log.Error("apmSvc.appAuthDelete find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Delete(a).Error; err != nil {
log.Error("apmSvc.appAuthDelete delete(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 3, int64(v.ID), "apmSvc.appAuthDelete", a)
c.JSON(nil, err)
}
func appTree(c *bm.Context) {
v := new(struct {
Bu string `form:"bu"`
Team string `form:"team"`
Name string `form:"name"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
username := name(c)
trees, err := apmSvc.Trees(c, username, c.Request.Header.Get("Cookie"))
if err != nil {
log.Error("apmSvc.appTree error(%v)", err)
c.JSON(nil, err)
return
}
var data []string
temp := make(map[string]string)
if v.Bu == "" && v.Team == "" {
for _, val := range trees {
nameArr := strings.Split(val.Path, ".")
newName := nameArr[1]
if f := temp[newName]; f == "" {
data = append(data, newName)
temp[newName] = newName
}
}
} else if v.Bu != "" && v.Team != "" && v.Name != "" {
for _, val := range trees {
nameArr := strings.Split(val.Path, ".")
if v.Bu == nameArr[1] && v.Team == nameArr[2] && v.Name == nameArr[3] {
data = append(data, strconv.Itoa(val.TreeID))
}
}
} else if v.Bu != "" && v.Team != "" {
for _, val := range trees {
nameArr := strings.Split(val.Path, ".")
if v.Bu == nameArr[1] && v.Team == nameArr[2] {
newName := nameArr[1] + "." + nameArr[2] + "." + nameArr[3]
if f := temp[newName]; f == "" {
data = append(data, nameArr[3])
temp[newName] = newName
}
}
}
} else if v.Bu != "" {
for _, val := range trees {
nameArr := strings.Split(val.Path, ".")
if v.Bu == nameArr[1] {
newName := v.Bu + "." + nameArr[2]
if f := temp[newName]; f == "" {
data = append(data, nameArr[2])
temp[newName] = newName
}
}
}
}
c.JSON(data, nil)
}
func appCallerSearch(c *bm.Context) {
v := new(struct {
AppID string `form:"app_id"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var (
aa []*app.Auth
count int
lk = "%" + v.AppID + "%"
)
if v.AppID != "" {
err = apmSvc.DB.Where("app_id LIKE ?", lk).Group("app_tree_id").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
} else {
err = apmSvc.DB.Group("app_tree_id").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
}
if err != nil {
log.Error("apmSvc.appCallerSearch error(%v)", err)
c.JSON(nil, err)
return
}
if v.AppID != "" {
err = apmSvc.DB.Select("count(distinct(app_tree_id))").Where("app_id LIKE ?", lk).Model(&app.Auth{}).Count(&count).Error
} else {
err = apmSvc.DB.Select("count(distinct(app_tree_id))").Model(&app.Auth{}).Count(&count).Error
}
if err != nil {
log.Error("apmSvc.appCallerSearch count error(%v)", err)
c.JSON(nil, err)
return
}
type result struct {
AppTreeID int64 `gorm:"column:app_tree_id" json:"app_tree_id"`
AppID string `gorm:"column:app_id" json:"app_id"`
Services []*app.Auth
}
var results []*result
if count > 0 {
var in []int64
auth := []*app.Auth{}
for _, val := range aa {
in = append(in, val.AppTreeID)
fmt.Printf("apptreeid=%v", val.AppTreeID)
}
apmSvc.DB.Where("app_tree_id in (?)", in).Find(&auth)
for _, vv := range aa {
rs := new(result)
rs.AppTreeID = vv.AppTreeID
rs.AppID = vv.AppID
for _, vvv := range auth {
if vv.AppTreeID == vvv.AppTreeID {
rs.Services = append(rs.Services, vvv)
}
}
results = append(results, rs)
}
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: results,
Total: count,
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,134 @@
package http
import (
"context"
"flag"
"fmt"
"net/url"
"path/filepath"
"testing"
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/service"
"go-common/library/log"
xhttp "go-common/library/net/http/blademaster"
. "github.com/smartystreets/goconvey/convey"
)
var (
_domain = "http://127.0.0.1:8000"
_contentType = "application/x-www-form-urlencoded"
_cookie = "username=fengshanshan; _AJSESSIONID=cf400491a236da90f27fb1b9bb9c4e2d; sven-apm=994ae2b6d290e584488443f9cc4733fbee7a88a4cd376135b1295f4cf81231de"
_realIP = "172.16.33.134"
_configuri = "%s/x/admin/apm/canal/apply/config"
_jsonstring = `[{ "schema":"123","table":[ {"name":"abc","primarykey":["order_id","new_id"],"omitfield":["new","old"]} , {"name":"def","primarykey":["order_id","new_id"],"omitfield":["new","old"] } ,{"name":"sfg","primarykey":["order_id","new_id"],"omitfield":["new","old"]} ],"databus": { "group": "LiveTime-LiveLive-P","addr": "172.16.33.158:6205"}},{ "schema":"456","table":[ {"name":"abc" ,"primarykey":["order_id","new_id"],"omitfield":["new","old"]} , {"name":"def" } ,{"name":"sfg"} ], "databus": {"group": "AccAnswer-MainManager-S","addr": "172.16.33.158:6205"}}]`
)
func init() {
dir, _ := filepath.Abs("../cmd/apm-admin-test.toml")
flag.Parse()
flag.Set("conf", dir)
conf.Init()
log.Init(conf.Conf.Log)
apmSvc = service.New(conf.Conf)
Init(conf.Conf, apmSvc)
}
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data string `json:"data"`
}
func requests(method, uri, realIP string, params url.Values, res interface{}) (err error) {
client := xhttp.NewClient(conf.Conf.HTTPClient)
req, err := client.NewRequest(method, uri, realIP, params)
if err != nil {
return
}
req.Header.Set("X-BACKEND-BILI-REAL-IP", _realIP)
req.Header.Set("Content-Type", _contentType)
req.Header.Set("Cookie", _cookie)
if err = client.Do(context.TODO(), req, &res); err != nil {
return
}
return
}
func TestApplyDetailToConfig(t *testing.T) {
Convey("TestApply register nonconfig and no canal_apply", t, func() {
params := url.Values{}
params.Set("addr", "10.20.30.34:8902")
params.Set("databases", _jsonstring)
params.Set("mark", "demo")
params.Set("user", "admin")
params.Set("password", "admin")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_configuri, _domain), "", params, &res)
So(res.Code, ShouldEqual, 70015)
})
Convey("TestApplyAddrIllegal", t, func() {
params := url.Values{}
params.Set("addr", "172.16.33.2553308")
params.Set("databases", _jsonstring)
params.Set("mark", "demo")
params.Set("user", "admin")
params.Set("passwd", "admin")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_configuri, _domain), "", params, &res)
So(res.Code, ShouldEqual, 70002)
//So(res.Message, ShouldContainSubstring, "addr参数不合法")
})
Convey("TestApplyExist", t, func() {
params := url.Values{}
params.Set("addr", "10.20.30.34:8902")
params.Set("databases", _jsonstring)
params.Set("mark", "demo")
params.Set("user", "admin")
params.Set("passwd", "admin")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_configuri, _domain), "", params, &res)
So(res.Code, ShouldEqual, 0)
//So(res.Message, ShouldContainSubstring, "己提交申请")
})
Convey("TestApplyAddRequestParamError", t, func() {
params := url.Values{}
params.Set("leader", "fss")
params.Set("remark", "test")
params.Set("project", "main.web-svr")
res := Response{}
_ = requests("POST", fmt.Sprintf(_configuri, _domain), "", params, &res)
So(res.Code, ShouldEqual, -400)
})
}
func TestApplyExist(t *testing.T) {
Convey("TestApply register nonconfig and no canal_apply", t, func() {
params := url.Values{}
params.Set("addr", "10.20.30.34:8902")
params.Set("databases", _jsonstring)
params.Set("mark", "demo")
params.Set("user", "a")
params.Set("password", "a")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_configuri, _domain), "", params, &res)
t.Logf("%+v", res)
So(res.Code, ShouldEqual, 70015)
})
}

View File

@@ -0,0 +1,291 @@
package http
import (
"context"
"strings"
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/canal"
"go-common/app/admin/main/apm/model/user"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
const (
_upsertMasterInfo = "INSERT INTO master_info (addr,remark,leader,cluster) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE remark=?,leader=?,cluster=?"
)
//canalList get canalinfo list
func canalList(c *bm.Context) {
var err error
v := new(canal.ListReq)
if err = c.Bind(v); err != nil {
return
}
data, _ := apmSvc.ProcessCanalList(c, v)
c.JSON(data, nil)
}
//canalList get canalinfo add
func canalAdd(c *bm.Context) {
v := new(canal.Canal)
var err error
if err = c.Bind(v); err != nil {
return
}
username := name(c)
err = apmSvc.ApplyAdd(c, v, username)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
//canalList get canalinfo edit
func canalEdit(c *bm.Context) {
v := new(canal.EditReq)
var err error
if err = c.Bind(v); err != nil {
return
}
username := name(c)
if err = apmSvc.ApplyEdit(c, v, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
//canalDelete 根据addr查询对应id进行软删除
func canalDelete(c *bm.Context) {
var err error
v := new(canal.ScanReq)
if err = c.Bind(v); err != nil {
return
}
username := name(c)
if err = apmSvc.ApplyDelete(c, v, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
//canalScanByAddrFromConfig 根据Addr查询对应有效的配置
func canalScanByAddrFromConfig(c *bm.Context) {
var confData *canal.Results
cookie := c.Request.Header.Get("Cookie")
v := new(canal.ScanReq)
var err error
if err = c.Bind(v); err != nil {
return
}
username := name(c)
if confData, err = apmSvc.GetScanInfo(c, v, username, cookie); err != nil {
c.JSON(nil, err)
return
}
c.JSON(confData, nil)
}
func canalApplyList(c *bm.Context) {
v := new(canal.ListReq)
var err error
if err = c.Bind(v); err != nil {
return
}
data, err := apmSvc.ProcessApplyList(c, v)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
//canalApplyDetailToConfig is
func canalApplyDetailToConfig(c *bm.Context) {
var (
username string
err error
v = new(canal.ConfigReq)
cookie = c.Request.Header.Get("Cookie")
)
if u, err := c.Request.Cookie("username"); err == nil {
username = u.Value
} else {
username = "third"
}
if err = c.Bind(v); err != nil {
return
}
//judge legal params
f := strings.Contains(v.Addr, ":")
if !f {
log.Error("canalApplyAdd addr not standard error(%v)", err)
c.JSON(nil, ecode.CanalAddrFmtErr)
return
}
if v.User != "" && v.Password != "" {
if err = apmSvc.CheckMaster(c, v); err != nil {
c.JSON(nil, err)
return
}
}
if err = apmSvc.ProcessCanalInfo(c, v, username); err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.ProcessConfigInfo(c, v, cookie, username); err != nil {
c.JSON(nil, err)
return
}
go apmSvc.SendWechatMessage(context.Background(), v.Addr, canal.TypeMap[canal.TypeApply], "", username, v.Mark, conf.Conf.Canal.Reviewer)
c.JSON(nil, err)
}
//canalApplyConfigEdit is
func canalApplyConfigEdit(c *bm.Context) {
cookie := c.Request.Header.Get("Cookie")
v := new(canal.ConfigReq)
if err := c.Bind(v); err != nil {
return
}
ap := &canal.Apply{}
err := apmSvc.DBCanal.Model(&canal.Apply{}).Select("`operator`").Where("addr=?", v.Addr).Find(ap).Error
if err != nil {
log.Error("no apply error", err)
err = ecode.CanalAddrNotFound
c.JSON(nil, err)
return
}
username := name(c)
err = apmSvc.Permit(c, username, user.CanalView)
err0 := apmSvc.Permit(c, username, user.CanalEdit)
if err != nil || (username != ap.Operator && err0 != nil) {
log.Error("permit(%v, %s,%s)", username, err)
c.JSON(nil, ecode.AccessDenied)
return
}
if v.User != "" && v.Password != "" {
if err = apmSvc.CheckMaster(c, v); err != nil {
c.JSON(nil, err)
return
}
}
if err0 != nil {
v = &canal.ConfigReq{
Addr: v.Addr,
MonitorPeriod: v.MonitorPeriod,
Databases: v.Databases,
Project: v.Project,
Leader: v.Leader,
Mark: v.Mark,
}
}
//judge legal params
f := strings.Contains(v.Addr, ":")
if !f {
log.Error("canalApplyAdd addr not standard error(%v)", err)
c.JSON(nil, ecode.CanalAddrFmtErr)
return
}
if err = apmSvc.ProcessCanalInfo(c, v, username); err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.ProcessConfigInfo(c, v, cookie, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
//canalAddrAll get canal all addr info
func canalAddrAll(c *bm.Context) {
var (
list []string
items []*canal.Canal
)
err := apmSvc.DBCanal.Model(&canal.Canal{}).Where("is_delete= 0").Select("`addr`").Scan(&items).Error
if err != nil {
log.Error("canalAddrAll get addr error(%v)", err)
c.JSON(nil, err)
return
}
for _, v := range items {
list = append(list, v.Addr)
}
c.JSON(list, nil)
}
// canal 审核
func canalApplyApprovalProcess(c *bm.Context) {
var (
err error
)
cookie := c.Request.Header.Get("Cookie")
res := map[string]interface{}{}
v := new(struct {
ID int `form:"id" validate:"required"`
State int8 `form:"state" validate:"required"`
})
if err = c.Bind(v); err != nil {
return
}
username := name(c)
apply := &canal.Apply{}
if err = apmSvc.DBCanal.Where("id = ?", v.ID).First(apply).Error; err != nil {
log.Error("canalApplyApprovalProcess id error(%v)", err)
c.JSON(nil, err)
return
}
if !(apply.State == 1 || apply.State == 2) {
log.Error("canalApplyApprovalProcess apply.state error(%v)", apply.State)
res["message"] = "只有申请中和打回才可审核"
c.JSONMap(res, ecode.RequestErr)
return
}
if !(v.State == 2 || v.State == 3 || v.State == 4) {
log.Error("canalApplyApprovalProcess v.state error(%v)", v.State)
res["message"] = "state值范围2,3,4"
c.JSONMap(res, ecode.RequestErr)
return
}
ups := map[string]interface{}{
"state": v.State,
}
if v.State == 3 && apply.State != 3 {
if err = apmSvc.UpdateProcessTag(c, apply.ConfID, cookie); err != nil {
log.Error("apmSvc.UpdateProcessTag error(%v)", apply.ID)
c.JSON(nil, err)
return
}
if err = apmSvc.DBCanal.Exec(_upsertMasterInfo, apply.Addr, apply.Remark, apply.Leader, apply.Cluster, apply.Remark, apply.Leader, apply.Cluster).Error; err != nil {
log.Error("canalProcess update master_info error(%v)", err)
c.JSONMap(nil, err)
return
}
}
// 更新apply
if err = apmSvc.DBCanal.Model(apply).Where("id = ?", apply.ID).Update(ups).Error; err != nil {
log.Error("canalApplyApprovalProcess update error(%v)", apply.ID)
res["message"] = "修改状态失败"
c.JSONMap(res, err)
return
}
go apmSvc.SendWechatMessage(context.Background(), apply.Addr, canal.TypeMap[canal.TypeReview], canal.TypeMap[v.State], username, "", []string{apply.Operator})
c.JSON(nil, err)
}

View File

@@ -0,0 +1,143 @@
package http
import (
"fmt"
"net/url"
"testing"
"go-common/app/admin/main/apm/model/canal"
. "github.com/smartystreets/goconvey/convey"
)
var (
_listuri = "%s/x/admin/apm/canal"
_scanurl = "%s/x/admin/apm/canal/scan"
_canalediturl = "%s/x/admin/apm/canal/apply/edit"
_addrallurl = "%s/x/admin/apm/canal/addrs"
_adduri = "%s/x/admin/apm/canal/add"
_deleteuri = "%s/x/admin/apm/canal/delete"
_edituri = "%s/x/admin/apm/canal/edit"
_applyurl = "%s/x/admin/apm/canal/apply"
)
func TestCanalList(t *testing.T) {
Convey("TestCanalList", t, func() {
params := url.Values{}
params.Set("project", "main.web-svr")
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data *canal.Paper `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_listuri, _domain), "", params, &res)
t.Logf("res:%+v", res.Data)
So(res.Code, ShouldEqual, 0)
})
}
func TestCanalAdd(t *testing.T) {
Convey("TestCanalAdd exists", t, func() {
params := url.Values{}
params.Set("addr", "172.16.33.866:3308")
params.Set("bin_name", "fss")
params.Set("bin_pos", "1")
params.Set("remark", "admin")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_adduri, _domain), "", params, &res)
t.Logf("res:%+v", res)
//So(res.Message, ShouldContainSubstring, "exist")
//So(res.Code, ShouldEqual, -400)
})
}
func TestCanalEdit(t *testing.T) {
Convey("TestCanalEdit", t, func() {
params := url.Values{}
params.Set("id", "8384")
params.Set("bin_name", "rtwew")
params.Set("bin_pos", "20")
params.Set("remark", "inesww")
params.Set("project", "main.web-svrq")
params.Set("leader", "dsa")
res := Response{}
_ = requests("POST", fmt.Sprintf(_edituri, _domain), "", params, &res)
t.Logf("res:%+v", res)
})
}
func TestCanalDelete(t *testing.T) {
Convey("TestCanalDelete", t, func() {
params := url.Values{}
params.Set("addr", "ewe")
res := Response{}
_ = requests("POST", fmt.Sprintf(_deleteuri, _domain), "", params, &res)
t.Logf("res:%+v", res)
})
}
func TestScanFromConfig(t *testing.T) {
Convey("TestScanFromConfig", t, func() {
params := url.Values{}
params.Set("addr", "10.20.30.34:8902")
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data *canal.Results `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_scanurl, _domain), "", params, &res)
t.Logf("res:%+v", res.Data.Document)
})
}
func TestApplyLists(t *testing.T) {
Convey("TestApplyList", t, func() {
params := url.Values{}
//params.Set("addr", "172.16.33.243:3308")
params.Set("project", "main.web-svr")
params.Set("status", "1")
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data *canal.Paper `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_applyurl, _domain), "", params, &res)
t.Logf("res:%v", res.Data)
})
}
func TestApplyConfigEdit(t *testing.T) {
Convey("TestApplyConfigEdit", t, func() {
params := url.Values{}
params.Set("addr", "10.20.30.37:8902")
params.Set("databases", _jsonstring)
params.Set("mark", "fss")
params.Set("user", "admin")
params.Set("password", "admin")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_canalediturl, _domain), "", params, &res)
t.Logf("res:%v", res)
})
}
func TestCanalAddrAll(t *testing.T) {
Convey("TestCanalAddrAll", t, func() {
params := url.Values{}
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data []string `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_addrallurl, _domain), "", params, &res)
t.Logf("res:%v", res.Data)
})
}

View File

@@ -0,0 +1,9 @@
package http
import (
bm "go-common/library/net/http/blademaster"
)
func dapperProxy(c *bm.Context) {
apmSvc.DapperProxy(c.Writer, c.Request)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
package http
import (
"strings"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func discoveryProxy(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/discovery/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.DiscoveryProxy(c, req.Method, req.URL.Path[idx+len("/x/admin/apm/discovery/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func discoveryProxyNoAuth(c *bm.Context) {
req := c.Request
data, err := apmSvc.DiscoveryProxy(c, req.Method, "fetch", req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,492 @@
package http
import (
"encoding/json"
"go-common/app/admin/main/apm/model/ecode"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func ecodeList(c *bm.Context) {
v := new(struct {
Code string `form:"code"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var (
cs []*codes.Codes
count int
lk = "%" + v.Code + "%"
)
if v.Code != "" {
err = apmSvc.DB.Where("CAST(code AS CHAR) LIKE ? OR message LIKE ?", lk, lk).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&cs).Error
} else {
err = apmSvc.DB.Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&cs).Error
}
if err != nil {
log.Error("apmSvc.EcodeList error(%v)", err)
c.JSON(nil, err)
return
}
if v.Code != "" {
err = apmSvc.DB.Where("CAST(code AS CHAR) LIKE ? OR message LIKE ?", lk, lk).Model(&codes.Codes{}).Count(&count).Error
} else {
err = apmSvc.DB.Model(&codes.Codes{}).Count(&count).Error
}
if err != nil {
log.Error("apmSvc.EcodeList count error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: cs,
Total: count,
}
c.JSON(data, nil)
}
func ecodeAdd(c *bm.Context) {
v := new(struct {
Code int32 `form:"code" validate:"required"`
Message string `form:"message" validate:"required"`
HantMessage string `form:"hant_message"`
Level int8 `form:"level" default:"2"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
cnt := 0
if err = apmSvc.DB.Model(&codes.Codes{}).Where("code=?", v.Code).Count(&cnt).Error; err != nil {
log.Error("apmSvc.EcodeAdd count error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
username := name(c)
code := &codes.Codes{
Code: v.Code,
Message: v.Message,
HantMessage: v.HantMessage,
Level: v.Level,
Operator: username,
}
if err = apmSvc.DB.Create(&code).Error; err != nil {
log.Error("apmSvc.EcodeAdd create error(%v)", err)
c.JSON(nil, err)
return
}
apmSvc.SendLog(*c, username, 0, 1, code.ID, "apmSvc.EcodeAdd", code)
c.JSON(nil, err)
}
func ecodeEdit(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
Code int32 `form:"code" validate:"required"`
Message string `form:"message" validate:"required"`
HantMessage string `form:"hant_message"`
Level int8 `form:"level" default:"2"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
code := &codes.Codes{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(code).Error; err != nil {
log.Error("apmSvc.EcodeEdit find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
username := name(c)
ups := map[string]interface{}{
"code": v.Code,
"message": v.Message,
"operator": username,
"hant_message": v.HantMessage,
"level": v.Level,
}
if err = apmSvc.DB.Model(&codes.Codes{}).Where("id = ?", v.ID).Updates(ups).Error; err != nil {
log.Error("apmSvc.EcodeEdit updates error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": v.ID,
"Update": ups,
"Old": code,
}
apmSvc.SendLog(*c, username, 0, 2, v.ID, "apmSvc.EcodeEdit", sqlLog)
c.JSON(nil, err)
}
func ecodeDelete(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
code := &codes.Codes{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(code).Error; err != nil {
log.Error("apmSvc.EcodeDelete find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Delete(code).Error; err != nil {
log.Error("apmSvc.EcodeDelete delete(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 3, code.ID, "apmSvc.EcodeDelete", code)
c.JSON(nil, err)
}
func getEcodes(c *bm.Context) {
v := new(struct {
Interval1 int `form:"interval1" default:"0"`
Interval2 int `form:"interval2" default:"0"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
codes := []*codes.Codes{}
if err = apmSvc.DB.Where("code >= ? and code <= ?", v.Interval1, v.Interval2).Find(&codes).Error; err != nil {
log.Error("getEcodes error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(codes, nil)
}
func syncEcodes(c *bm.Context) {
res := map[string]interface{}{}
v := new(struct {
Data string `form:"data"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
username := name(c)
var Codes []*codes.Codes
err = json.Unmarshal([]byte(v.Data), &Codes)
if err != nil {
res["message"] = "解析失败"
c.JSONMap(res, err)
return
}
var in []int32
for _, val := range Codes {
in = append(in, val.Code)
}
oldCodes := []*codes.Codes{}
if err = apmSvc.DB.Where("code in (?)", in).Find(&oldCodes).Error; err != nil {
log.Error("getEcodes error(%v)", err)
c.JSON(nil, err)
return
}
tmp := make(map[int32]struct{})
for _, val := range oldCodes {
tmp[val.Code] = struct{}{}
}
var code *codes.Codes
tx := apmSvc.DB.Begin()
for _, val := range Codes {
code = &codes.Codes{}
code.Code = val.Code
code.Message = val.Message
code.HantMessage = val.HantMessage
code.Level = val.Level
code.Operator = username
if _, ok := tmp[val.Code]; ok {
//update
if err = tx.Model(codes.Codes{}).Where("code = ?", val.Code).Updates(code).Error; err != nil {
tx.Rollback()
c.JSON(nil, err)
return
}
} else {
//create
if err = tx.Create(code).Error; err != nil {
tx.Rollback()
c.JSON(nil, err)
return
}
}
}
tx.Commit()
c.JSON(nil, err)
}
func getProdEcodes(c *bm.Context) {
v := new(struct {
Interval1 string `form:"interval1" default:"0"`
Interval2 string `form:"interval2" default:"0"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
Data, err := apmSvc.GetCodes(c, v.Interval1, v.Interval2)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(Data, nil)
}
func codeLangsList(c *bm.Context) {
v := new(struct {
Code string `form:"code"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var (
cs []*codes.Codes
count int
lk = "%" + v.Code + "%"
in []int64
ts []*codes.CodeMsg
res []*codes.NewCodes
)
if v.Code != "" {
err = apmSvc.DB.Where("CAST(code AS CHAR) LIKE ? OR message LIKE ?", lk, lk).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&cs).Error
} else {
err = apmSvc.DB.Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&cs).Error
}
if err != nil {
log.Error("apmSvc.EcodeList error(%v)", err)
c.JSON(nil, err)
return
}
for _, val := range cs {
in = append(in, val.ID)
}
err = apmSvc.DB.Where("code_id in(?)", in).Find(&ts).Error
if err != nil {
log.Error("apmSvc.EcodeList error(%v)", err)
c.JSON(nil, err)
return
}
for _, val := range cs {
list := make([]*codes.CodeMsg, 0)
for _, vv := range ts {
if vv.CodeID == val.ID {
list = append(list, vv)
}
}
res = append(res, &codes.NewCodes{Codes: val, List: list})
}
if v.Code != "" {
err = apmSvc.DB.Where("CAST(code AS CHAR) LIKE ? OR message LIKE ?", lk, lk).Model(&codes.Codes{}).Count(&count).Error
} else {
err = apmSvc.DB.Model(&codes.Codes{}).Count(&count).Error
}
if err != nil {
log.Error("apmSvc.EcodeList count error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: res,
Total: count,
}
c.JSON(data, nil)
}
func ecodeLangsAdd(c *bm.Context) {
res := map[string]interface{}{}
v := new(struct {
Data string `form:"data" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var Codes []*codes.CodeMsg
err = json.Unmarshal([]byte(v.Data), &Codes)
if err != nil {
res["message"] = "解析失败"
c.JSONMap(res, err)
return
}
username := name(c)
for _, val := range Codes {
if !(val.CodeID > 0 && len(val.Locale) > 0 && len(val.Msg) > 0) {
err = ecode.RequestErr
res["message"] = "数据有误"
c.JSONMap(res, err)
return
}
code := &codes.CodeMsg{
CodeID: val.CodeID,
Locale: val.Locale,
Msg: val.Msg,
Operator: username,
}
if err = apmSvc.DB.Create(&code).Error; err != nil {
log.Error("apmSvc.ecodeLangsAdd create error(%v)", err)
c.JSON(nil, err)
return
}
apmSvc.SendLog(*c, username, 0, 1, code.ID, "apmSvc.ecodeLangsAdd", code)
}
c.JSON(nil, err)
}
func ecodeLangsEdit(c *bm.Context) {
res := map[string]interface{}{}
v := new(struct {
Data string `form:"data" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var Codes []*codes.CodeMsg
err = json.Unmarshal([]byte(v.Data), &Codes)
if err != nil {
res["message"] = "解析失败"
c.JSONMap(res, err)
return
}
username := name(c)
for _, val := range Codes {
code := &codes.CodeMsg{}
if err = apmSvc.DB.Where("id = ?", val.ID).First(code).Error; err != nil {
log.Error("apmSvc.ecodeLangsEdit find(%d) error(%v)", val.ID, err)
c.JSON(nil, err)
return
}
ups := map[string]interface{}{
"operator": username,
"msg": val.Msg,
"locale": val.Locale,
}
if err = apmSvc.DB.Model(&codes.CodeMsg{}).Where("id = ?", val.ID).Updates(ups).Error; err != nil {
log.Error("apmSvc.ecodeLangsEdit updates error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": val.ID,
"Update": ups,
"Old": code,
}
apmSvc.SendLog(*c, username, 0, 2, val.ID, "apmSvc.ecodeLangsEdit", sqlLog)
}
c.JSON(nil, err)
}
func ecodeLangsDelete(c *bm.Context) {
v := new(struct {
CID int64 `form:"cid" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
code := &codes.CodeMsg{}
if err = apmSvc.DB.Where("id = ?", v.CID).First(code).Error; err != nil {
log.Error("apmSvc.ecodeLangsDelete find(%d) error(%v)", v.CID, err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Delete(code).Error; err != nil {
log.Error("apmSvc.ecodeLangsDelete delete(%d) error(%v)", v.CID, err)
c.JSON(nil, err)
return
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 3, code.ID, "apmSvc.ecodeLangsDelete", code)
c.JSON(nil, err)
}
func ecodeLangsSave(c *bm.Context) {
res := map[string]interface{}{}
v := new(struct {
Data string `form:"data" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var Codes []*codes.CodeMsg
err = json.Unmarshal([]byte(v.Data), &Codes)
if err != nil {
res["message"] = "解析失败"
c.JSONMap(res, err)
return
}
username := name(c)
for _, val := range Codes {
code := &codes.CodeMsg{}
if val.ID == 0 {
if !(val.CodeID > 0 && len(val.Locale) > 0 && len(val.Msg) > 0) {
err = ecode.RequestErr
res["message"] = "数据有误"
c.JSONMap(res, err)
return
}
code = &codes.CodeMsg{
CodeID: val.CodeID,
Locale: val.Locale,
Msg: val.Msg,
Operator: username,
}
if err = apmSvc.DB.Create(&code).Error; err != nil {
log.Error("apmSvc.ecodeLangsSvae create error(%v)", err)
c.JSON(nil, err)
return
}
apmSvc.SendLog(*c, username, 0, 1, code.ID, "apmSvc.ecodeLangsAdd", code)
} else {
if err = apmSvc.DB.Where("id = ?", val.ID).First(code).Error; err != nil {
log.Error("apmSvc.ecodeLangsSvae find(%d) error(%v)", val.ID, err)
c.JSON(nil, err)
return
}
ups := map[string]interface{}{
"operator": username,
"msg": val.Msg,
"locale": val.Locale,
}
if err = apmSvc.DB.Model(&codes.CodeMsg{}).Where("id = ?", val.ID).Updates(ups).Error; err != nil {
log.Error("apmSvc.ecodeLangsSave updates error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": val.ID,
"Update": ups,
"Old": code,
}
apmSvc.SendLog(*c, username, 0, 2, val.ID, "apmSvc.ecodeLangsSave", sqlLog)
}
}
c.JSON(nil, err)
}

View File

@@ -0,0 +1,17 @@
package http
//import (
// "testing"
//
// "flag"
//
// . "github.com/smartystreets/goconvey/convey"
//)
//
//func TestEcodeList(t *testing.T) {
// Convey("test ecode list", t, func() {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// c := request(nil)
// ecodeList(&c)
// })
//}

View File

@@ -0,0 +1,283 @@
package http
import (
"net/http"
"go-common/app/admin/main/apm/conf"
per "go-common/app/admin/main/apm/model/user"
"go-common/app/admin/main/apm/service"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
mpermit "go-common/library/net/http/blademaster/middleware/permit"
)
var (
apmSvc *service.Service
authSrv *mpermit.Permit
)
// Init init http sever instance.
func Init(c *conf.Config, s *service.Service) {
apmSvc = s
authSrv = mpermit.New(c.Auth)
engine := bm.DefaultServer(c.BM)
innerRouter(engine)
if err := engine.Start(); err != nil {
log.Error("engine.Start error(%v)", err)
panic(err)
}
}
// innerRouter init inner router.
func innerRouter(e *bm.Engine) {
e.Ping(ping)
b := e.Group("x/admin/apm", authSrv.Verify())
{
code := b.Group("/ecode")
{
code.POST("/add", permit(per.EcodeEdit), ecodeAdd)
code.POST("/edit", permit(per.EcodeEdit), ecodeEdit)
code.POST("/delete", permit(per.EcodeEdit), ecodeDelete)
code.POST("/sync/ecodes", permit(per.EcodeEdit), syncEcodes)
code.POST("/langs/add", permit(per.EcodeEdit), ecodeLangsAdd)
code.POST("/langs/edit", permit(per.EcodeEdit), ecodeLangsEdit)
code.POST("/langs/delete", permit(per.EcodeEdit), ecodeLangsDelete)
code.POST("/langs/save", permit(per.EcodeEdit), ecodeLangsSave)
}
user := b.Group("/user")
{
user.GET("/auth", userAuth)
user.GET("/rule/states", userRuleStates)
user.POST("/apply", userApply)
user.POST("/apply/edit", permit(per.UserEdit), userApplyEdit)
user.GET("/users", userList)
user.GET("/info", permit(per.UserView), userInfo)
user.POST("/edit", permit(per.UserEdit), userEdit)
user.GET("/modules", permit(per.UserEdit), userModules)
user.GET("/rules", permit(per.UserEdit), userRules)
user.POST("/module/edit", permit(per.UserEdit), userModulesEdit)
user.POST("/rule/edit", permit(per.UserEdit), userRulesEdit)
user.GET("/applies", userApplies)
user.POST("/audit", userAudit)
// sync
user.GET("/tree/sync", userSyncTree)
user.GET("/tree/appids", userTreeAppids)
user.GET("/tree/discovery", userTreeDiscovery)
}
databus := b.Group("/databus")
{
// project
databus.GET("/projects", permit(per.DatabusKeyView), databusProjects)
// app
databus.GET("/apps", permit(per.DatabusKeyView), databusApps)
databus.POST("/app/add", permit(per.DatabusKeyEdit), databusAppAdd)
databus.POST("/app/edit", permit(per.DatabusKeyEdit), databusAppEdit)
// group
databus.GET("/groups", permit(per.DatabusGroupView), databusGroups)
databus.GET("/group/projects", permit(per.DatabusGroupView), databusGroupProjects)
databus.GET("/group/consumer/addrs", permit(per.DatabusGroupView), databusConsumerAddrs)
databus.POST("/group/sub/add", permit(per.DatabusGroupEdit), databusGroupSubAdd)
databus.POST("/group/pub/add", permit(per.DatabusGroupEdit), databusGroupPubAdd)
databus.POST("/group/delete", permit(per.DatabusGroupEdit), databusGroupDelete)
databus.POST("/group/rename", permit(per.DatabusGroupEdit), databusGroupRename)
databus.GET("/group/offset", permit(per.DatabusGroupView), databusGroupOffset)
databus.POST("/group/marked", permit(per.DatabusGroupEdit), databusGroupMarked)
databus.POST("/group/begin", permit(per.DatabusGroupEdit), databusGroupBegin)
databus.POST("/group/new/offset", permit(per.DatabusGroupEdit), databusGroupNewOffset)
databus.POST("/group/time", permit(per.DatabusGroupEdit), databusGroupTime)
// topic
databus.GET("/topics", permit(per.DatabusTopicView), databusTopics)
databus.GET("/topic/names", permit(per.DatabusGroupView), databusTopicNames)
databus.POST("/topic/add", permit(per.DatabusTopicEdit), databusTopicAdd)
databus.POST("/topic/edit", permit(per.DatabusTopicEdit), databusTopicEdit)
databus.GET("/topic/all", permit(per.DatabusGroupView), databusTopicAll)
// alarm
databus.POST("/alarm/edit", permit(per.DatabusGroupView), databusAlarmEdit)
databus.POST("/alarm/init", permit(per.DatabusGroupView), databusAlarmInit)
databus.POST("/alarm/all/edit", permit(per.DatabusGroupView), databusAlarmAllEdit)
// apply
databus.GET("/apply/list", permit(per.DatabusGroupView), databusApplyList)
databus.POST("/apply/pub/add", permit(per.DatabusGroupView), databusApplyPubAdd)
databus.POST("/apply/sub/add", permit(per.DatabusGroupView), databusApplySubAdd)
databus.POST("/apply/edit", permit(per.DatabusGroupView), databusApplyEdit)
databus.POST("/apply/approval/process", permit(per.DatabusGroupApply), databusApplyApprovalProcess)
// notify
databus.GET("/notify/apply/list", permit(per.DatabusGroupView), databusNotifyList)
databus.POST("/notify/edit", permit(per.DatabusNotifyEdit), databusNotifyEdit)
databus.POST("/notify/apply/add", permit(per.DatabusGroupView), databusNotifyApplyAdd)
// databus.POST("/notify/filter/add", databusNotifyFilterAdd)
// databus.POST("/notify/filter/edit", databusNotifyFilterEdit)
// message
databus.GET("/message/fetch", permit(per.DatabusGroupView), databusMsgFetch)
}
canal := b.Group("/canal")
{
canal.GET("", permit(per.CanalView), canalList)
canal.POST("/add", permit(per.CanalEdit), canalAdd)
canal.POST("/edit", permit(per.CanalEdit), canalEdit)
canal.POST("/delete", permit(per.CanalEdit), canalDelete)
canal.GET("/scan", permit(per.CanalView), canalScanByAddrFromConfig)
e.POST("x/admin/apm/canal/apply/config", canalApplyDetailToConfig)
canal.GET("/addrs", permit(per.CanalView), canalAddrAll)
canal.POST("/apply/edit", permit(per.CanalView), canalApplyConfigEdit)
canal.GET("/apply", permit(per.CanalView), canalApplyList)
canal.POST("/apply/approval/process", permit(per.CanalEdit), canalApplyApprovalProcess)
}
need := b.Group("/need")
{
need.GET("/list", needList)
need.POST("/add", needAdd)
need.POST("/edit", needEdit)
need.POST("/verify", permit(per.NeedVerify), needVerify)
need.POST("/thumbsup", needThumbsUp)
need.GET("/vote/list", permit(per.NeedVerify), needVoteList)
}
discovery := b.Group("/discovery")
{
discovery.GET("/", discoveryProxy)
}
app := b.Group("/app")
{
app.GET("/list", permit(per.AppView), appList)
app.POST("/add", permit(per.AppEdit), appAdd)
app.POST("/edit", permit(per.AppEdit), appEdit)
app.POST("/delete", permit(per.AppEdit), appDelete)
app.GET("/auth/list", permit(per.AppAuthView), appAuthList)
app.POST("/auth/add", permit(per.AppEdit), appAuthAdd)
app.POST("/auth/edit", permit(per.AppEdit), appAuthEdit)
app.POST("/auth/delete", permit(per.AppEdit), appAuthDelete)
app.GET("/caller/search", permit(per.AppEdit), appCallerSearch)
//tree
app.GET("/tree", permit(per.AppEdit), appTree)
}
platform := b.Group("/platform")
{
platform.GET("/search/get/", permit(per.PlatformSearchView), searchProxyGet)
platform.POST("/search/post/", permit(per.PlatformSearchView), searchProxyPost)
platform.GET("/reply/get/", permit(per.PlatformReplyView), replyProxyGet)
platform.POST("/reply/post/", permit(per.PlatformReplyView), replyProxyPost)
platform.GET("/tag/get/", permit(per.PlatformTagView), tagProxyGet)
platform.POST("/tag/post/", permit(per.PlatformTagView), tagProxyPost)
platform.GET("/bfs/get/", permit(per.BFSView), bfsProxyGet)
platform.POST("/bfs/post/", permit(per.BFSEdit), bfsProxyPost)
platform.GET("/reply/feed/get/", permit(per.PlatformReplyView), replyFeedProxyGet)
platform.POST("/reply/feed/post/", permit(per.PlatformReplyView), replyFeedProxyPost)
}
p := b.Group("/pprof")
{
p.GET("/profile", permit(per.PerformanceManager), buildSvg)
p.GET("/svg", permit(per.PerformanceManager), readSvg)
p.GET("/heap", permit(per.PerformanceManager), heap)
p.GET("/flame", permit(per.PerformanceManager), flame)
p.GET("/", permit(per.PerformanceManager), pprof)
}
ut := b.Group("/ut")
{
ut.GET("/merge/list", utList)
ut.GET("/detail/list", utDetail)
ut.GET("/history/commit", utHistoryCommit)
ut.GET("/rank/list", utRank)
ut.GET("/rank/user", userRank)
ut.GET("/quality/trend", utQATrend)
ut.GET("/commits", utGeneralCommit)
ut.GET("/dashboard/pkgs", utDashPkgsTree)
ut.GET("/dashboard/curve", utDashCurve)
ut.GET("/dashboard/histogram", utDashHistogram)
ut.GET("/dashboard/histogram/user", utDashUserDetail)
ut.GET("/app/list", utApps)
}
open := b.Group("/open")
{
open.GET("/get/", permit(per.OpenView), openProxyGet)
open.POST("/post/", permit(per.OpenView), openProxyPost)
}
}
// no auth
d := e.Group("x/admin/apm")
notAuth := d.Group("/")
{
notAuth.GET("canal/alarm", canalList) // 运维canal报警接口
notAuth.GET("databus/clusters", databusClusters)
notAuth.GET("databus/alarm", databusAlarm) // 运维databus告警用
notAuth.GET("databus/alarms", databusAlarms) // 有所有group diff查询时间巨长2分钟起板
notAuth.GET("ut/baseline", utBaseline)
notAuth.GET("noauth/discovery/fetch", discoveryProxyNoAuth) // 提供给自动告警查询对应实例
notAuth.GET("ecode", ecodeList)
notAuth.POST("databus/opsmind", databusOpsmind)
notAuth.POST("databus/opsmind/remove", databusOpsmindRemove)
notAuth.GET("databus/query", databusQuery)
notAuth.GET("ecode/get/ecodes", getEcodes)
notAuth.GET("ecode/get/prod/ecodes", getProdEcodes)
notAuth.GET("ecode/langs", codeLangsList)
}
dapper := d.Group("/dapper")
{
dapper.GET("/", dapperProxy)
}
up := d.Group("/ut")
{
up.POST("/upload", upload)
up.POST("/upload/app", uploadApp)
//up.GET("/tyrant", check)
up.GET("/check", check)
up.POST("/merge/set", utSetMerged)
up.GET("/dashboard/history/commit", dashHistoryCommit)
up.GET("/git/report", utGitReport)
}
m := d.Group("/monitor")
{
m.GET("/apps", appNameList)
m.GET("/prometheus", prometheusList)
m.GET("/broadcast", broadcastList)
m.GET("/databus", databusList)
m.GET("/online", onlineList)
}
warn := d.Group("/warn")
{
warn.POST("/active", activeWarning)
}
}
// Paper paper.
type Paper struct {
Total int `json:"total"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items interface{} `json:"items"`
}
// ping check server ok.
func ping(c *bm.Context) {
if err := apmSvc.Ping(c); err != nil {
c.AbortWithStatus(http.StatusServiceUnavailable)
log.Error("apm-admin service ping error(%v)", err)
}
}
func permit(rule string) bm.HandlerFunc {
return func(ctx *bm.Context) {
usernameI, _ := ctx.Get("username")
username, ok := usernameI.(string)
if !ok || username == "" {
ctx.JSON(nil, ecode.NoLogin)
ctx.Abort()
return
}
if rule == "" {
return
}
if err := apmSvc.Permit(ctx, username, rule); err != nil {
log.Error("apmSvc.Permit(%s, %s) error(%v)", username, rule, err)
ctx.JSON(nil, err)
ctx.Abort()
}
}
}

View File

@@ -0,0 +1,53 @@
package http
import (
bm "go-common/library/net/http/blademaster"
)
func appNameList(c *bm.Context) {
c.JSON(apmSvc.AppNameList(c), nil)
}
func prometheusList(c *bm.Context) {
v := new(struct {
AppName string `form:"app_name" validate:"required"`
Method string `form:"method" validate:"required"`
MType string `form:"mtype" default:"count"`
})
if err := c.Bind(v); err != nil {
return
}
pts, err := apmSvc.PrometheusList(c, v.AppName, v.Method, v.MType)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(pts, nil)
}
func onlineList(c *bm.Context) {
ols, err := apmSvc.OnlineList(c)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(ols, nil)
}
func broadcastList(c *bm.Context) {
bcs, err := apmSvc.BroadCastList(c)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(bcs, nil)
}
func databusList(c *bm.Context) {
dbs, err := apmSvc.DataBusList(c)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(dbs, nil)
}

View File

@@ -0,0 +1,140 @@
package http
import (
"context"
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/need"
bm "go-common/library/net/http/blademaster"
)
// @params NListReq
// @router get /x/admin/apm/need/list
// @response NListResp
func needList(c *bm.Context) {
var (
infos []*need.NInfo
total int64
err error
)
username := name(c)
arg := new(need.NListReq)
if err = c.Bind(arg); err != nil {
return
}
if infos, total, err = apmSvc.NeedInfoList(c, arg, username); err != nil {
c.JSON(nil, err)
return
}
res := &need.NListResp{
Data: infos,
Total: total,
}
c.JSON(res, nil)
}
// @params NAddReq
// @router post /x/admin/apm/need/add
// @response EmpResp
func needAdd(c *bm.Context) {
var err error
username := name(c)
req := new(need.NAddReq)
if err = c.Bind(req); err != nil {
return
}
if err = apmSvc.NeedInfoAdd(c, req, username); err != nil {
c.JSON(nil, err)
return
}
go apmSvc.SendWeMessage(context.Background(), req.Title, need.VerifyType[need.NeedApply], "", username, conf.Conf.Superman)
go apmSvc.SendWeMessage(context.Background(), req.Title, need.VerifyType[need.NeedVerify], "", username, []string{username})
c.JSON(nil, err)
}
// @params NEditReq
// @router post /x/admin/apm/need/edit
// @response EmpResp
func needEdit(c *bm.Context) {
var err error
req := new(need.NEditReq)
if err = c.Bind(req); err != nil {
return
}
username := name(c)
if err = apmSvc.NeedInfoEdit(c, req, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
// @params NVerifyReq
// @router post /x/admin/apm/need/verify
// @response EmpResp
func needVerify(c *bm.Context) {
var (
err error
ni *need.NInfo
)
req := new(need.NVerifyReq)
if err = c.Bind(req); err != nil {
return
}
username := name(c)
if ni, err = apmSvc.NeedInfoVerify(c, req); err != nil {
c.JSON(nil, err)
return
}
go apmSvc.SendWeMessage(context.Background(), ni.Title, need.VerifyType[need.NeedReview], need.VerifyType[req.Status], username, []string{username})
c.JSON(nil, err)
}
// @params Likereq
// @router post /x/admin/apm/need/thumbsup
// @response EmpResp
func needThumbsUp(c *bm.Context) {
var err error
req := new(need.Likereq)
if err = c.Bind(req); err != nil {
return
}
username := name(c)
if err = apmSvc.NeedInfoVote(c, req, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
// @params Likereq
// @router get /x/admin/need/vote/list
// @response VoteListResp
func needVoteList(c *bm.Context) {
var (
votes []*need.UserLikes
total int64
err error
)
req := new(need.Likereq)
if err = c.Bind(req); err != nil {
return
}
if votes, total, err = apmSvc.NeedVoteList(c, req); err != nil {
c.JSON(nil, err)
return
}
res := &need.VoteListResp{
Data: votes,
Total: total,
}
c.JSON(res, nil)
}

View File

@@ -0,0 +1,108 @@
package http
import (
"fmt"
"net/url"
"testing"
"github.com/smartystreets/goconvey/convey"
"go-common/app/admin/main/apm/model/need"
)
var (
_nadduri = "%s/x/admin/apm/need/add"
_nlisturi = "%s/x/admin/apm/need/list"
_nedituri = "%s/x/admin/apm/need/edit"
_nverifyuri = "%s/x/admin/apm/need/verify"
_nthumsupuri = "%s/x/admin/apm/need/thumbsup"
_nvotelisturi = "%s/x/admin/apm/need/vote/list"
)
func TestNeedList(t *testing.T) {
convey.Convey("", t, func() {
params := url.Values{}
params.Set("pn", "1")
params.Set("ps", "5")
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data *need.NListResp `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_nlisturi, _domain), "", params, &res)
t.Logf("res%+v", res.Data)
})
}
func TestNeedAdd(t *testing.T) {
convey.Convey("TestNeedAdd normal", t, func() {
params := url.Values{}
params.Set("title", "dsds")
params.Set("content", "sds")
res := Response{}
_ = requests("POST", fmt.Sprintf(_nadduri, _domain), "", params, &res)
t.Logf("res%+v", res)
convey.So(res.Code, convey.ShouldEqual, 0)
})
//convey.Convey("TestNeedAdd params error", t, func() {
// // params := url.Values{}
// // params.Set("title", "提一个小需求阿斯加德卡萨")
// // res := Response{}
// // _ = requests("POST", fmt.Sprintf(_nadduri, _domain), "", params, &res)
// // t.Logf("res%+v", res)
// // convey.So(res.Code, convey.ShouldEqual, -400)
// //})
}
func TestNeedEdit(t *testing.T) {
convey.Convey("TestNeedEdit", t, func() {
params := url.Values{}
params.Set("title", "fss")
params.Set("content", "fss")
params.Set("id", "26")
res := Response{}
_ = requests("POST", fmt.Sprintf(_nedituri, _domain), "", params, &res)
convey.So(res.Code, convey.ShouldEqual, 0)
})
}
func TestNeedVerify(t *testing.T) {
convey.Convey("TestNeedVerify", t, func() {
params := url.Values{}
params.Set("status", "2")
params.Set("id", "28")
res := Response{}
_ = requests("POST", fmt.Sprintf(_nverifyuri, _domain), "", params, &res)
convey.So(res.Code, convey.ShouldEqual, 70018)
})
}
func TestNeedThumbsUp(t *testing.T) {
convey.Convey("TestNeedThumbsUp", t, func() {
params := url.Values{}
params.Set("req_id", "29")
params.Set("like_type", "1")
res := Response{}
_ = requests("POST", fmt.Sprintf(_nthumsupuri, _domain), "", params, &res)
convey.So(res.Code, convey.ShouldEqual, 0)
})
}
func TestVoteList(t *testing.T) {
convey.Convey("TestVoteList", t, func() {
params := url.Values{}
params.Set("req_id", "11")
params.Set("like_type", "1")
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data *need.VoteListResp `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_nvotelisturi, _domain), "", params, &res)
t.Logf("res%+v", res)
})
}

View File

@@ -0,0 +1,134 @@
package http
// import (
// "context"
// "encoding/json"
// "flag"
// "fmt"
// "net/http"
// "net/url"
// "strings"
// "testing"
// "time"
// "go-common/app/admin/main/apm/conf"
// "go-common/app/admin/main/apm/service"
// bm "go-common/library/net/http/context"
// )
// var path = "http://127.0.0.1:80/xx"
// type resp struct {
// http.ResponseWriter
// }
// func TestNotifyApply(t *testing.T) {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// conf.Init()
// apmSvc = service.New(conf.Conf)
// params := url.Values{}
// params.Set("cluster", "test_kafka_9092-266")
// params.Set("topic_name", "AccLabour-T")
// params.Set("remark", "test")
// params.Set("project", "main.web-svr")
// params.Set("topic_remark", "test")
// params.Set("offset", "new")
// params.Set("filter", "1")
// params.Set("concurrent", "10")
// params.Set("callback", `{"aa":1}`)
// params.Set("filters", `[{"field":"svv","condition":1,"value":"v"}]`)
// req, _ := http.NewRequest("POST", path, strings.NewReader(params.Encode()))
// req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.ParseForm()
// ctx := bm.NewContext(context.TODO(), req, resp{}, time.Second)
// ctx.Set("username", "haoguanwei")
// ctx.Request().ParseForm()
// //databusNotifyApplyAdd(ctx)
// fmt.Println(ctx.Result())
// }
// func TestApplyList(t *testing.T) {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// conf.Init()
// apmSvc = service.New(conf.Conf)
// params := url.Values{}
// // params.Set("cluster", "test_kafka_9092-266")
// // params.Set("topic_name", "AccAnswer-T")
// // params.Set("project", "main.web-svr")
// req, _ := http.NewRequest("POST", path, strings.NewReader(params.Encode()))
// req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.ParseForm()
// ctx := bm.NewContext(context.TODO(), req, resp{}, time.Second)
// ctx.Set("username", "haoguanwei")
// ctx.Request().ParseForm()
// //databusApplyList(ctx)
// data, err := json.Marshal(ctx.Result())
// fmt.Println(string(data), err)
// }
// func TestNotifyList(t *testing.T) {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// conf.Init()
// apmSvc = service.New(conf.Conf)
// params := url.Values{}
// params.Set("cluster", "test_kafka_9092-266")
// params.Set("topic_name", "AccAnswer-T")
// params.Set("remark", "test")
// //params.Set("project", "main.web-svr")
// req, _ := http.NewRequest("POST", path, strings.NewReader(params.Encode()))
// req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.ParseForm()
// ctx := bm.NewContext(context.TODO(), req, resp{}, time.Second)
// ctx.Set("username", "haoguanwei")
// ctx.Request().ParseForm()
// //databusNotifyList(ctx)
// data, err := json.Marshal(ctx.Result())
// fmt.Println(string(data), err)
// }
// func TestNotifyEdit(t *testing.T) {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// conf.Init()
// apmSvc = service.New(conf.Conf)
// params := url.Values{}
// params.Set("n_id", "159")
// params.Set("offset", "new")
// params.Set("filter", "0")
// params.Set("state", "0")
// params.Set("concurrent", "10")
// params.Set("callback", `{"aaq":1}`)
// params.Set("filters", `[{"id":4,"field":"test","condition":1,"value":"vvv"}]`)
// req, _ := http.NewRequest("POST", path, strings.NewReader(params.Encode()))
// req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.ParseForm()
// ctx := bm.NewContext(context.TODO(), req, resp{}, time.Second)
// ctx.Set("username", "haoguanwei")
// ctx.Request().ParseForm()
// //databusNotifyEdit(ctx)
// data, err := json.Marshal(ctx.Result())
// fmt.Println(string(data), err)
// }
// func TestApplyProcess(t *testing.T) {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// conf.Init()
// apmSvc = service.New(conf.Conf)
// params := url.Values{}
// params.Set("id", "165")
// params.Set("state", "3")
// req, _ := http.NewRequest("POST", path, strings.NewReader(params.Encode()))
// req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.ParseForm()
// ctx := bm.NewContext(context.TODO(), req, resp{}, time.Second)
// ctx.Set("username", "haoguanwei")
// ctx.Request().ParseForm()
// //databusApplyApprovalProcess(ctx)
// fmt.Println(ctx.Result())
// }

View File

@@ -0,0 +1,38 @@
package http
import (
"strings"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func openProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/open/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.OpenProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/open/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func openProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/open/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.OpenProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/open/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,158 @@
package http
import (
"strings"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func searchProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/search/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/platform/search/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func searchProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/search/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/platform/search/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func replyProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/reply/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/platform/reply/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func replyProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/reply/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/platform/reply/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func tagProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/tag/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/platform/tag/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func tagProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/tag/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/platform/tag/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func bfsProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/bfs/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/platform/bfs/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func bfsProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/bfs/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/platform/bfs/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func replyFeedProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/reply/feed/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/platform/reply/feed/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func replyFeedProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/reply/feed/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/platform/reply/feed/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,155 @@
package http
import (
"io/ioutil"
"net/http"
"go-common/app/admin/main/apm/conf"
mpprof "go-common/app/admin/main/apm/model/pprof"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func buildSvg(c *bm.Context) {
v := new(struct {
URL string `form:"url" validate:"required"`
URI string `form:"uri" validate:"required"`
SvgName string `form:"name" validate:"required"`
Time int64 `form:"time" validate:"required"`
HostName string `form:"hostname" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
if !(v.URI == "profile" || v.URI == "heap") {
c.JSON(nil, ecode.RequestErr)
return
}
err = apmSvc.Pprof(v.URL, v.URI, v.SvgName, v.HostName, v.Time, 2)
c.JSON(nil, err)
}
func readSvg(c *bm.Context) {
v := new(struct {
SvgName string `form:"name" validate:"required"`
URI string `form:"uri" validate:"required"`
HostName string `form:"hostname" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
url := conf.Conf.Pprof.Dir + "/" + v.SvgName + "_" + v.HostName + "_" + v.URI + ".svg"
data, err := ioutil.ReadFile(url)
if err != nil {
log.Error("readfile error(%v)", err)
c.JSON(nil, err)
return
}
c.Bytes(http.StatusOK, "image/svg+xml; charset=utf-8", data)
}
func heap(c *bm.Context) {
v := new(struct {
URL string `form:"url" validate:"required"`
URI string `form:"uri" validate:"required"`
SvgName string `form:"name" validate:"required"`
HostName string `form:"hostname" validate:"required"`
})
var err error
var data []byte
if err = c.Bind(v); err != nil {
return
}
if v.URI != "heap" {
c.JSON(nil, ecode.RequestErr)
return
}
err = apmSvc.Pprof(v.URL, v.URI, v.SvgName, v.HostName, 1, 1)
if err != nil {
c.JSON(nil, err)
return
}
url := conf.Conf.Pprof.Dir + "/" + v.SvgName + "_" + v.HostName + "_" + v.URI + ".svg"
data, err = ioutil.ReadFile(url)
if err != nil {
log.Error("readfile error(%v)", err)
c.JSON(nil, err)
return
}
c.Bytes(http.StatusOK, "image/svg+xml; charset=utf-8", data)
}
func flame(c *bm.Context) {
v := new(struct {
URL string `form:"url" validate:"required"`
URI string `form:"uri" validate:"required"`
SvgName string `form:"name" validate:"required"`
Time int64 `form:"time"`
HostName string `form:"hostname" validate:"required"`
})
var err error
var data []byte
if err = c.Bind(v); err != nil {
return
}
if !(v.URI == "profile" || v.URI == "heap") {
c.JSON(nil, ecode.RequestErr)
return
}
if v.URI == "heap" {
err = apmSvc.Torch(c, v.URL, v.URI, v.SvgName, v.HostName, 1, 1)
if err != nil {
c.JSON(nil, err)
return
}
url := conf.Conf.Pprof.Dir + "/" + v.SvgName + "_" + v.HostName + "_" + v.URI + "_flame.svg"
data, err = ioutil.ReadFile(url)
if err != nil {
log.Error("readfile error(%v)", err)
c.JSON(nil, err)
return
}
c.Bytes(http.StatusOK, "image/svg+xml; charset=utf-8", data)
} else {
err = apmSvc.Torch(c, v.URL, v.URI, v.SvgName, v.HostName, v.Time, 2)
c.JSON(nil, err)
}
}
func activeWarning(c *bm.Context) {
// var (
// err error
// body []byte
// )
// if body, err = ioutil.ReadAll(c.Request.Body); err != nil {
// c.JSON(nil, fmt.Errorf("warning body empty"))
// return
// }
// if err = apmSvc.ActiveWarning(c, string(body)); err != nil {
// c.JSON(nil, err)
// return
// }
// ioutil.ReadAll You need close body.
c.JSON(nil, nil)
}
func pprof(c *bm.Context) {
var (
err error
pws = make([]*mpprof.Warn, 0)
req = &mpprof.Params{}
)
if err = c.Bind(req); err != nil {
c.JSON(nil, err)
return
}
if pws, err = apmSvc.PprofWarn(c, req); err != nil {
c.JSON(nil, err)
return
}
c.JSON(pws, nil)
}

View File

@@ -0,0 +1,139 @@
package http
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
type result struct {
Code int `gorm:"column:code" json:"code"`
Message string `gorm:"column:message" json:"message"`
}
//http client
func httpDo(method, uri, cookie string, params url.Values) (data *result, err error) {
client := &http.Client{}
req, err := http.NewRequest(method, uri, strings.NewReader(params.Encode()))
if err != nil {
return
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Cookie", cookie)
resp, err := client.Do(req)
if err != nil {
return
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
defer resp.Body.Close()
data = &result{}
json.Unmarshal(body, data)
return
}
func TestHttpDo(t *testing.T) {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
params := url.Values{"id": {"20"}, "state": {"3"}}
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=429fca48067ef8234335cddda8a7d64ba46662e3d9448d38df6184f63a37e165"
t.Error("print log")
if res, err := httpDo("POST", uri, cookie, params); err != nil {
fmt.Println("There are some error~")
fmt.Printf("%s", err)
} else {
fmt.Println("code:", res.Code)
fmt.Println("message:", res.Message)
}
}
func TestProcess(t *testing.T) {
Convey("if apply.State == 1, state =[2,3,4]; expect: code ==0", t, func() {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=f78e8fadc7f41048258acf43f5e9abee59f7b7a5bb6312b81fd31a21945fd21e"
params := url.Values{"id": {"7"}, "state": {"2"}}
res, err := httpDo("POST", uri, cookie, params)
if err != nil {
t.Error(err)
} else {
So(res.Code, ShouldEqual, 0)
}
})
}
func TestProcess2(t *testing.T) {
Convey("if apply.State == 2, state =[2,3,4]; expect: code ==0", t, func() {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=f78e8fadc7f41048258acf43f5e9abee59f7b7a5bb6312b81fd31a21945fd21e"
params := url.Values{"id": {"8"}, "state": {"3"}}
res, err := httpDo("POST", uri, cookie, params)
if err != nil {
t.Error(err)
} else {
So(res.Code, ShouldEqual, 0)
}
})
}
func TestProcess3(t *testing.T) {
Convey("if apply.State == 3, state =[2,3,4]; expect: code == -400", t, func() {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=f78e8fadc7f41048258acf43f5e9abee59f7b7a5bb6312b81fd31a21945fd21e"
params := url.Values{"id": {"9"}, "state": {"2"}}
res, err := httpDo("POST", uri, cookie, params)
if err != nil {
t.Error(err)
} else {
So(res.Code, ShouldEqual, -400)
So(res.Message, ShouldEqual, "只有申请中和打回才可审核")
}
})
}
func TestProcess4(t *testing.T) {
Convey("if apply.State == 4, state =[2,3,4]; expect: code == -400", t, func() {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=f78e8fadc7f41048258acf43f5e9abee59f7b7a5bb6312b81fd31a21945fd21e"
params := url.Values{"id": {"10"}, "state": {"2"}}
res, err := httpDo("POST", uri, cookie, params)
if err != nil {
t.Error(err)
} else {
So(res.Code, ShouldEqual, -400)
So(res.Message, ShouldEqual, "只有申请中和打回才可审核")
}
})
}
func TestProcess5(t *testing.T) {
Convey("if apply.State == 1, state !=[2,3,4]; expect: code == -400", t, func() {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=f78e8fadc7f41048258acf43f5e9abee59f7b7a5bb6312b81fd31a21945fd21e"
params := url.Values{"id": {"11"}, "state": {"5"}}
res, err := httpDo("POST", uri, cookie, params)
if err != nil {
t.Error(err)
} else {
So(res.Code, ShouldEqual, -400)
So(res.Message, ShouldEqual, "state值范围2,3,4")
}
})
}

View File

@@ -0,0 +1,61 @@
package http
import (
"go-common/app/admin/main/apm/model/ut"
bm "go-common/library/net/http/blademaster"
)
// @params RankReq
// @router get /x/admin/apm/ut/rank/list
// @response RankResp
func utRank(c *bm.Context) {
var (
err error
topTens []*ut.RankResp
bottomTens []*ut.RankResp
rankList = make(map[string]interface{})
UserList *ut.RankResp
)
v := new(struct {
UserName string `form:"username"`
})
if err = c.Bind(v); err != nil {
return
}
if topTens, err = apmSvc.RankTen(c, "desc"); err != nil {
c.JSON(nil, err)
return
}
if bottomTens, err = apmSvc.RankTen(c, "asc"); err != nil {
c.JSON(nil, err)
return
}
if UserList, err = apmSvc.UserRank(c, v.UserName); err != nil {
c.JSON(nil, err)
return
}
rankList["topten"] = topTens
rankList["bottomten"] = bottomTens
rankList["user"] = UserList
c.JSON(rankList, nil)
}
// /x/admin/apm/ut/rank/user
func userRank(c *bm.Context) {
var (
err error
UserList *ut.RankResp
)
v := new(struct {
UserName string `form:"username"`
})
if err = c.Bind(v); err != nil {
return
}
if UserList, err = apmSvc.UserRank(c, v.UserName); err != nil {
c.JSON(nil, err)
return
}
c.JSON(UserList, nil)
}

View File

@@ -0,0 +1,732 @@
{
"swagger": "2.0",
"info": {
"title": "go-common api",
"description": "api",
"version": "1.0",
"contact": {
"email": "lintanghui@bilibili.com"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"paths": {
"/x/admin/apm/need/add": {
"post": {
"operationId": "/x/admin/apm/need/add",
"parameters": [
{
"in": "query",
"name": "title",
"required": true,
"type": "string"
},
{
"in": "query",
"name": "content",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/EmpResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/need/edit": {
"post": {
"operationId": "/x/admin/apm/need/edit",
"parameters": [
{
"in": "query",
"name": "content",
"type": "string"
},
{
"in": "query",
"name": "id",
"required": true,
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "title",
"type": "string"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/EmpResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/need/list": {
"get": {
"operationId": "/x/admin/apm/need/list",
"parameters": [
{
"in": "query",
"name": "ps",
"description": " 默认值 20",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "pn",
"description": " 默认值 1",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "status",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "reporter",
"type": "string"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/NListResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/need/thumbsup": {
"post": {
"operationId": "/x/admin/apm/need/thumbsup",
"parameters": [
{
"in": "query",
"name": "like_type",
"type": "integer",
"format": "int32"
},
{
"in": "query",
"name": "req_id",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/EmpResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/need/verify": {
"post": {
"operationId": "/x/admin/apm/need/verify",
"parameters": [
{
"in": "query",
"name": "id",
"required": true,
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "status",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/EmpResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/ut/detail/list": {
"get": {
"operationId": "/x/admin/apm/ut/detail/list",
"parameters": [
{
"in": "query",
"name": "merge_id",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "commit_id",
"type": "string"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/Detail",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/ut/history/commit": {
"get": {
"operationId": "/x/admin/apm/ut/history/commit",
"parameters": [
{
"in": "query",
"name": "merge_id",
"required": true,
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "commit_id",
"type": "string"
},
{
"in": "query",
"name": "pn",
"description": " 默认值 1",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "ps",
"description": " 默认值 20",
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/HistoryCommitResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/ut/info/list": {
"get": {
"operationId": "/x/admin/apm/ut/info/list",
"parameters": [
{
"in": "query",
"name": "merge_id",
"description": " 默认值 0",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "username",
"type": "string"
},
{
"in": "query",
"name": "pn",
"description": " 默认值 1",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "ps",
"description": " 默认值 20",
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/Paper",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/need/vote/list": {
"get": {
"operationId": "/x/admin/need/vote/list",
"parameters": [
{
"in": "query",
"name": "req_id",
"required": true,
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "like_type",
"type": "integer",
"format": "int32"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/VoteListResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
}
},
"definitions": {
"Detail": {
"title": "Detail",
"description": "Detail ut_detail",
"type": "object",
"properties": {
"Assertions": {
"type": "integer",
"format": "int64"
},
"CTime": {
"type": "string",
"format": "string"
},
"CommitID": {
"type": "string"
},
"Coverage": {
"type": "string"
},
"Failures": {
"type": "integer",
"format": "int64"
},
"HTMLURL": {
"type": "string"
},
"ID": {
"type": "integer",
"format": "int64"
},
"MTime": {
"type": "string",
"format": "string"
},
"MergeID": {
"type": "integer",
"format": "int64"
},
"PKG": {
"type": "string"
},
"Panics": {
"type": "integer",
"format": "int64"
},
"PassRate": {
"type": "string"
},
"Passed": {
"type": "integer",
"format": "int64"
},
"ReportURL": {
"type": "string"
},
"Skipped": {
"type": "integer",
"format": "int64"
},
"Username": {
"type": "string"
}
}
},
"EmpResp": {
"title": "EmpResp",
"description": "EmpResp is empty resp.",
"type": "object"
},
"HistoryCommitResp": {
"title": "HistoryCommitResp",
"description": "HistoryCommitResp struct",
"type": "object",
"properties": {
"Assertions": {
"type": "integer",
"format": "int64"
},
"CommitID": {
"type": "string"
},
"CovChange": {
"type": "string"
},
"Coverage": {
"type": "string"
},
"Failures": {
"type": "integer",
"format": "int64"
},
"ID": {
"type": "integer",
"format": "int64"
},
"MergeID": {
"type": "integer",
"format": "int64"
},
"Panics": {
"type": "integer",
"format": "int64"
},
"PassRate": {
"type": "string"
},
"Passed": {
"type": "integer",
"format": "int64"
},
"Skipped": {
"type": "integer",
"format": "int64"
}
}
},
"NInfo": {
"title": "NInfo",
"description": "NInfo struct",
"type": "object",
"properties": {
"CTime": {
"type": "string",
"format": "string"
},
"Content": {
"type": "string"
},
"DislikeCounts": {
"type": "integer",
"format": "int64"
},
"ID": {
"type": "integer",
"format": "int64"
},
"LikeCounts": {
"type": "integer",
"format": "int64"
},
"LikeState": {
"type": "integer",
"format": "int32"
},
"MTime": {
"type": "string",
"format": "string"
},
"Reporter": {
"type": "string"
},
"Status": {
"type": "integer",
"format": "int32"
},
"Title": {
"type": "string"
}
}
},
"NListResp": {
"title": "NListResp",
"description": "NListResp is list resp struct",
"type": "object",
"properties": {
"Data": {
"type": "array",
"items": {
"$ref": "#/definitions/NInfo",
"type": "object"
}
},
"Total": {
"type": "integer",
"format": "int64"
}
}
},
"Paper": {
"title": "Paper",
"description": "Paper canallist resp",
"type": "object",
"properties": {
"Items": {
"$ref": "#/definitions/false",
"type": "object"
},
"Pn": {
"type": "integer",
"format": "int64"
},
"Ps": {
"type": "integer",
"format": "int64"
},
"Total": {
"type": "integer",
"format": "int64"
}
}
},
"UserLikes": {
"title": "UserLikes",
"description": "UserLikes struct",
"type": "object",
"properties": {
"CTime": {
"type": "string",
"format": "string"
},
"ID": {
"type": "integer",
"format": "int64"
},
"LikeType": {
"type": "integer",
"format": "int32"
},
"MTime": {
"type": "string",
"format": "string"
},
"ReqID": {
"type": "integer",
"format": "int64"
},
"User": {
"type": "string"
}
}
},
"VoteListResp": {
"title": "VoteListResp",
"description": "VoteListResp is vote resp struct",
"type": "object",
"properties": {
"Data": {
"type": "array",
"items": {
"$ref": "#/definitions/UserLikes",
"type": "object"
}
},
"Total": {
"type": "integer",
"format": "int64"
}
}
},
"false": null
}
}

View File

@@ -0,0 +1,135 @@
package http
import (
"encoding/json"
"io/ioutil"
"mime/multipart"
"time"
"go-common/app/admin/main/apm/model/ut"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func upload(c *bm.Context) {
var (
file multipart.File
body []byte
htmlURL string
reportURL string
dataURL string
err error
pkg = new(ut.PkgAnls)
files []*ut.File
res = &ut.UploadRes{}
header *multipart.FileHeader
)
c.Request.ParseMultipartForm(32 << 20)
if err = c.Bind(res); err != nil {
return
}
log.Info("ut.upload(%d) start! current_time(%d)", res.MergeID, time.Now().Unix())
defer log.Info("ut.upload(%d) finished. current_time(%d)", res.MergeID, time.Now().Unix())
if file, _, err = c.Request.FormFile("report_file"); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("report request upload err (%v)", err)
return
}
defer file.Close()
if body, err = ioutil.ReadAll(file); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("ioutil.ReadAll(c.Request().Body) error(%v)", err)
return
}
if body, err = apmSvc.ParseContent(c, body); err != nil {
c.JSON(err.Error(), err)
return
}
if pkg, err = apmSvc.CalcCount(c, body); err != nil {
c.JSON(nil, err)
return
}
if pkg.Assertions == 0 {
c.JSON("no result", nil)
return
}
if reportURL, err = apmSvc.Upload(c, "json", time.Now().Unix(), body); err != nil {
c.JSON(nil, err)
return
}
if file, header, err = c.Request.FormFile("data_file"); err == nil && header.Size > 0 {
defer file.Close()
if body, err = ioutil.ReadAll(file); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("Upload data request error(%v)", err)
return
}
if files, err = apmSvc.CalcCountFiles(c, res, body); err != nil {
c.JSON(nil, err)
log.Error("Upload data calcCount error(%v)", err)
return
}
if dataURL, err = apmSvc.Upload(c, "text/plain", time.Now().Unix(), body); err != nil {
c.JSON(nil, err)
return
}
}
if file, _, err = c.Request.FormFile("html_file"); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("html request upload err (%v)", err)
return
}
defer file.Close()
if body, err = ioutil.ReadAll(file); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("html read error(%v)", err)
return
}
if htmlURL, err = apmSvc.Upload(c, "html", time.Now().Unix(), body); err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.AddUT(c, pkg, files, res, dataURL, reportURL, htmlURL); err != nil {
c.JSON(nil, err)
return
}
// update ut_app has_ut = 1 && converage
if err = apmSvc.UpdateUTApp(c, pkg); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
// uploadApp upload path to ut_app
func uploadApp(c *bm.Context) {
var (
file multipart.File
body []byte
apps []*ut.App
err error
)
c.Request.ParseMultipartForm(32 << 20)
if file, _, err = c.Request.FormFile("path_file"); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("path request upload error(%v)", err)
return
}
defer file.Close()
if body, err = ioutil.ReadAll(file); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("path_file read error(%v)", err)
return
}
if err = json.Unmarshal(body, &apps); err != nil {
log.Error("json.Unmarshal error(%v)", err)
return
}
if err = apmSvc.AddUTApp(c, apps); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("apmSvc.AddUtApp error(%v)", err)
return
}
c.JSON(nil, err)
}

View File

@@ -0,0 +1,35 @@
package http
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func Test(t *testing.T) {
convey.Convey("upload", t, func() {
url := "http://127.0.0.1:7331/x/admin/apm/ut/upload"
payload := strings.NewReader("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; " +
"name=\"html_file\"\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; " +
"name=\"mid\"\r\n\r\n6\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; " +
"name=\"username\"\r\n\r\nchengxing\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: " +
"form-data; name=\"report_file\"\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
req.Header.Add("Cookie", "_AJSESSIONID=cf81d40c0e9d960a0ce89ceeb05c5670; username=chengxing; "+
"sven-apm=4104f6b8cb1d967a0dd45d6934638ba2bfc86cd239bf7bab095b8a1cc3f85b65")
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Cache-Control", "no-cache")
req.Header.Add("Postman-Token", "69b1317b-0b01-43a0-a85d-c899f64ae34e")
res, _ := http.DefaultClient.Do(req)
body, _ := ioutil.ReadAll(res.Body)
defer res.Body.Close()
fmt.Println(string(body))
})
}

View File

@@ -0,0 +1,788 @@
package http
import (
"strings"
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/user"
"go-common/library/conf/env"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"github.com/jinzhu/gorm"
)
func name(ctx *bm.Context) (name string) {
usernameI, _ := ctx.Get("username")
name, _ = usernameI.(string)
return
}
func userAuth(c *bm.Context) {
var (
usr = &user.User{}
username = name(c)
err error
mdls []*user.Module
rls []*user.Rule
super bool
)
if usr, err = apmSvc.GetUser(c, username); err != nil {
log.Error("apmSvc.userAuth error(%v)", err)
c.JSON(nil, err)
return
}
// err := apmSvc.DB.Where("username = ?", username).First(usr).Error
// if err == gorm.ErrRecordNotFound {
// usr.UserName = username
// usr.NickName = username
// err = apmSvc.DB.Create(usr).Error
// }
// if err != nil {
// log.Error("apmSvc.userAuth error(%v)", err)
// c.JSON(nil, err)
// return
// }
for _, u := range conf.Conf.Superman {
if u == username {
super = true
break
}
}
var (
ms []string
rs []string
)
if super {
for m := range user.Modules {
ms = append(ms, m)
for rl := range user.Rules {
if strings.HasPrefix(rl+"_", m) {
rs = append(rs, rl)
}
}
}
} else {
ms, rs = apmSvc.GetDefaultPermission(c)
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&mdls).Error; err != nil {
log.Error("apmSvc.userAuth modules error(%v)", err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&rls).Error; err != nil {
log.Error("apmSvc.userAuth rules error(%v)", err)
c.JSON(nil, err)
return
}
for _, m := range mdls {
ms = append(ms, m.Module)
}
for _, r := range rls {
rs = append(rs, r.Rule)
}
}
data := user.Result{
Super: super,
User: usr,
Env: env.DeployEnv,
Rules: append(ms, rs...),
}
c.JSON(data, nil)
}
func userRuleStates(c *bm.Context) {
username := name(c)
usr := &user.User{}
err := apmSvc.DB.Where("username = ?", username).First(usr).Error
if err != nil {
log.Error("apmSvc.userRuleStates error(%v)", err)
c.JSON(nil, err)
return
}
for _, u := range conf.Conf.Superman {
if u == username {
c.JSONMap(map[string]interface{}{
"message": "超级管理员拥有所有权限",
}, nil)
return
}
}
var (
//app *user.Apply
rls []*user.Rule
)
app := &user.Apply{}
if err = apmSvc.DB.Where("user_id=? AND status=?", usr.ID, 1).First(app).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("apm.Svc.userRuleStates error(%v)", err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&rls).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("apm.Svc.userRuleStates error(%v)", err)
c.JSON(nil, err)
return
}
trs := strings.Split(app.Rules, ",")
type ruleRes struct {
Rule string `json:"rule"`
Name string `json:"name"`
State int `json:"state"`
}
data := map[string][]*ruleRes{}
for module := range user.Modules {
if env.DeployEnv != env.DeployEnvProd && module == "CONFIG" {
continue
}
if user.Modules[module].Permit == user.PermitSuper {
continue
}
// if module == "USER" {
// continue
// }
NEXTRULE:
for rule := range user.Rules {
if !strings.HasPrefix(rule, module) {
continue
}
rr := &ruleRes{Rule: rule, Name: user.Rules[rule].Des, State: 0}
_, rdft := apmSvc.GetDefaultPermission(c)
for _, rl := range rdft {
if rule == rl {
rr.State = 1
data[module] = append(data[module], rr)
continue NEXTRULE
}
}
for _, rl := range rls {
if rule == rl.Rule {
rr.State = 1
data[module] = append(data[module], rr)
continue NEXTRULE
}
}
for _, tr := range trs {
if rule == tr {
rr.State = 2
data[module] = append(data[module], rr)
continue NEXTRULE
}
}
data[module] = append(data[module], rr)
}
}
c.JSON(map[string]interface{}{
"user": usr,
"rule_states": data,
}, nil)
}
func userApply(c *bm.Context) {
username := name(c)
usr := &user.User{}
if err := apmSvc.DB.Where("username = ?", username).First(usr).Error; err != nil {
log.Error("apmSvc.userApply error(%v)", err)
c.JSON(nil, err)
return
}
v := new(struct {
Rules []string `form:"rules,split" validate:"required"`
})
if err := c.Bind(v); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
for _, rule := range v.Rules {
if _, ok := user.Rules[rule]; !ok {
c.JSONMap(map[string]interface{}{
"message": "申请的操作不存在",
}, nil)
return
}
}
istr := strings.Join(v.Rules, ",")
m := &user.Apply{
UserID: usr.ID,
Rules: istr,
Status: 1,
}
db := apmSvc.DB.Model(&user.Apply{}).Create(m)
if err := db.Error; err != nil {
log.Error("apmSvc.userApply error(%v)", err)
c.JSON(nil, err)
return
}
c.JSONMap(map[string]interface{}{
"message": "申请成功",
}, nil)
}
func userApplyEdit(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
Rules []string `form:"rules,split" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
for _, r := range v.Rules {
if _, ok := user.Rules[r]; !ok {
c.JSONMap(map[string]interface{}{
"message": "申请的操作不存在",
}, nil)
return
}
}
username := name(c)
if err = apmSvc.DB.Model(&user.Apply{}).Where("status = 1 AND id = ?", v.ID).Update(map[string]interface{}{
"rules": strings.Join(v.Rules, ","), "admin": username}).Error; err != nil {
log.Error("apmSvc.userApplyEdit error(%v)", err)
c.JSON(nil, err)
return
}
c.JSONMap(map[string]interface{}{
"message": "修改成功",
}, nil)
}
func userAudit(c *bm.Context) {
username := name(c)
super := false
for _, u := range conf.Conf.Superman {
if u == username {
super = true
break
}
}
if !super {
c.JSON(nil, ecode.AccessDenied)
return
}
v := new(struct {
ID int64 `form:"id" validate:"required"`
Status int8 `form:"status" validate:"required"`
})
if err := c.Bind(v); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if !(v.Status == 2 || v.Status == 3) {
log.Error("apmSvc.userAudit error(%v)", v.Status)
c.JSONMap(map[string]interface{}{
"message": "status值范围为23",
}, ecode.RequestErr)
return
}
if err := apmSvc.DB.Model(&user.Apply{}).Where("id = ? AND status = ?", v.ID, 1).Updates(map[string]interface{}{"status": v.Status, "admin": username}).Error; err != nil {
log.Error("apmSvc.userAudit update user_apply error(%v)", err)
c.JSON(nil, err)
return
}
if v.Status == 3 {
c.JSONMap(map[string]interface{}{
"message": "权限审核不通过",
}, nil)
return
}
apps := &user.Apply{}
if err := apmSvc.DB.Where("id=?", v.ID).First(apps).Error; err != nil {
log.Error("apmSvc.userAudit find user_apply error(%v)", err)
c.JSON(nil, err)
return
}
rules := strings.Split(apps.Rules, ",")
for _, rule := range rules {
r := &user.Rule{}
apmSvc.DB.FirstOrCreate(r, &user.Rule{UserID: apps.UserID, Rule: rule})
for module := range user.Modules {
if strings.HasPrefix(rule, module) {
m := &user.Module{}
apmSvc.DB.FirstOrCreate(m, &user.Module{UserID: apps.UserID, Module: module})
}
}
}
c.JSONMap(map[string]interface{}{
"message": "权限审核通过",
}, nil)
}
func userApplies(c *bm.Context) {
username := name(c)
v := new(struct {
Pn int `form:"pn" default:"1" validate:"min=1"`
Ps int `form:"ps" default:"20" validate:"min=1"`
Name string `form:"name"`
})
err := c.Bind(v)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
var (
super bool
total int
applies []*user.Applies
)
for _, u := range conf.Conf.Superman {
if u == username {
super = true
break
}
}
if !super {
c.JSON(nil, ecode.AccessDenied)
return
}
if v.Name != "" {
err = apmSvc.DB.Raw(`SELECT user_apply.id, user_apply.user_id,user.username,user_apply.rules,user_apply.status
FROM user_apply LEFT JOIN user ON user_apply.user_id=user.id WHERE user_apply.status=? AND (user.username like ? OR user.nickname like ?)`,
1, "%"+v.Name+"%", "%"+v.Name+"%").Order("user_apply.id desc").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&applies).Error
} else {
err = apmSvc.DB.Raw(`SELECT user_apply.id, user_apply.user_id,user.username,user_apply.rules,user_apply.status
FROM user_apply LEFT JOIN user ON user_apply.user_id=user.id WHERE user_apply.status=?`,
1).Order("user_apply.id desc").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&applies).Error
}
// err := apmSvc.DB.Raw(`SELECT user_apply.id, user_apply.user_id,user.username,user_apply.rules,user_apply.status
// FROM user_apply LEFT JOIN user ON user_apply.user_id=user.id WHERE user_apply.status=?`, 1).Scan(&applies).Error
if err == gorm.ErrRecordNotFound {
c.JSONMap(map[string]interface{}{
"message": "当前没有任何申请",
}, nil)
return
}
if v.Name != "" {
err = apmSvc.DB.Model(&user.Apply{}).Joins("LEFT JOIN user ON user_apply.user_id=user.id").Where(`user_apply.status=?
AND (user.username like ? OR user.nickname like ?)`, 1, "%"+v.Name+"%", "%"+v.Name+"%").Count(&total).Error
} else {
err = apmSvc.DB.Model(&user.Apply{}).Joins(`LEFT JOIN user ON user_apply.user_id=user.id`).Where(`user_apply.status=?`, 1).Count(&total).Error
}
if err != nil {
log.Error("apmSvc.userApplies error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: applies,
Total: total,
}
c.JSON(data, nil)
}
func userList(c *bm.Context) {
v := new(struct {
Pn int `form:"pn" default:"1" validate:"min=1"`
Ps int `form:"ps" default:"20" validate:"min=1"`
Name string `form:"name"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var (
pts []*user.User
total int
)
s := "%" + v.Name + "%"
if v.Name != "" {
err = apmSvc.DB.Where("username LIKE ? OR nickname LIKE ?", s, s).Order("id").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&pts).Error
} else {
err = apmSvc.DB.Order("id").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&pts).Error
}
if err != nil {
log.Error("apmSvc.Users error(%v)", err)
c.JSON(nil, err)
return
}
if v.Name != "" {
err = apmSvc.DB.Where("username LIKE ? OR nickname LIKE ?", s, s).Model(&user.User{}).Count(&total).Error
} else {
err = apmSvc.DB.Model(&user.User{}).Count(&total).Error
}
if err != nil {
log.Error("apmSvc.Users count error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: pts,
Total: total,
}
c.JSON(data, nil)
}
func userInfo(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
log.Error("apmSvc.userInfo error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(usr, nil)
}
func userEdit(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
Nickname string `form:"nickname"`
Email string `form:"email"`
Phone string `form:"phone"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Model(&user.User{}).Where("id = ?", v.ID).Omit("id").UpdateColumns(v).Error; err != nil {
log.Error("apmSvc.userEdit error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": v.ID,
"Update": v,
"Old": usr,
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 2, int64(v.ID), "apmSvc.userEdit", sqlLog)
c.JSON(nil, err)
}
func userModules(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
log.Error("apmSvc.userInfo error(%v)", err)
c.JSON(nil, err)
return
}
var mdls []*user.Module
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&mdls).Error; err != nil {
log.Error("apmSvc.userAuth modules error(%v)", err)
c.JSON(nil, err)
return
}
var ms []string
for _, m := range mdls {
ms = append(ms, m.Module)
}
allMds := make(map[string]string)
for module := range user.Modules {
allMds[module] = user.Modules[module].Des
}
data := map[string]interface{}{
"owns": ms,
"modules": allMds,
}
c.JSON(data, nil)
}
func userRules(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
log.Error("apmSvc.userInfo error(%v)", err)
c.JSON(nil, err)
return
}
var (
mdls []*user.Module
rls []*user.Rule
)
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&mdls).Error; err != nil {
log.Error("apmSvc.userAuth modules error(%v)", err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&rls).Error; err != nil {
log.Error("apmSvc.userAuth rules error(%v)", err)
c.JSON(nil, err)
return
}
var rs []string
for _, r := range rls {
rs = append(rs, r.Rule)
}
allRls := map[string]string{}
for _, mdl := range mdls {
for rl, rlM := range user.Rules {
if strings.HasPrefix(rl+"_", mdl.Module) {
allRls[rl] = rlM.Des
}
}
}
data := map[string]interface{}{
"owns": rs,
"rules": allRls,
}
c.JSON(data, nil)
}
func userModulesEdit(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
Modules []string `form:"modules,split"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
var mdls []*user.Module
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&mdls).Error; err != nil {
log.Error("apmSvc.moduleEdit modules error(%v)", err)
c.JSON(nil, err)
return
}
var (
ns []*user.Module
ds []string
)
for _, m := range v.Modules {
if len(mdls) == 0 {
ns = append(ns, &user.Module{UserID: usr.ID, Module: m})
continue
}
for j, mdl := range mdls {
if m == mdl.Module {
break
}
if j+1 == len(mdls) {
ns = append(ns, &user.Module{UserID: usr.ID, Module: m})
}
}
}
for _, mdl := range mdls {
if len(v.Modules) == 0 {
ds = append(ds, mdl.Module)
continue
}
for j, m := range v.Modules {
if m == mdl.Module {
break
}
if j+1 == len(v.Modules) {
ds = append(ds, mdl.Module)
}
}
}
if err = apmSvc.DB.Exec("DELETE FROM user_module WHERE user_id=? AND module IN (?)", usr.ID, ds).Error; err != nil {
log.Error("apmSvc.moduleEdit delModule error(%v)", err)
c.JSON(nil, err)
return
}
var sqlLogs []*map[string]interface{}
sqlLog := &map[string]interface{}{
"SQLType": "delete",
"Where": "DELETE FROM user_module WHERE user_id=? AND module IN (?)",
"Value1": usr.ID,
"Value2": ds,
"Update": "",
"Old": "",
}
sqlLogs = append(sqlLogs, sqlLog)
username := name(c)
// apmSvc.SendLog(c, username, 0, 2, int64(v.ID), "apmSvc.moduleEdit", sqlLog)
for _, d := range ds {
if err = apmSvc.DB.Exec("DELETE FROM user_rule WHERE user_id=? AND rule LIKE ?", usr.ID, d+"_%").Error; err != nil {
log.Error("apmSvc.moduleEdit delModule error(%v)", err)
c.JSON(nil, err)
apmSvc.SendLog(*c, username, 0, 2, 0, "apmSvc.moduleEdit", sqlLogs)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "delete",
"Where": "DELETE FROM user_rule WHERE user_id=? AND rule LIKE ?",
"Value1": usr.ID,
"Value2": d + "_%",
"Update": "",
"Old": "",
}
sqlLogs = append(sqlLogs, sqlLog)
}
for _, n := range ns {
if err = apmSvc.DB.Create(n).Error; err != nil {
log.Error("apmSvc.moduleEdit addModule error(%v)", err)
c.JSON(nil, err)
apmSvc.SendLog(*c, username, 0, 2, 0, "apmSvc.moduleEdit", sqlLogs)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "add",
"Content": n,
}
sqlLogs = append(sqlLogs, sqlLog)
}
apmSvc.SendLog(*c, username, 0, 2, 0, "apmSvc.moduleEdit", sqlLogs)
c.JSON(nil, err)
}
func userRulesEdit(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
Rules []string `form:"rules,split"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
var mdls []*user.Module
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&mdls).Error; err != nil {
log.Error("apmSvc.moduleEdit modules error(%v)", err)
c.JSON(nil, err)
return
}
if len(mdls) == 0 {
log.Error("apmSvc.moduleEdit have not module error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
for _, rl := range v.Rules {
var has bool
for _, mdl := range mdls {
if has = strings.HasPrefix(rl, mdl.Module); has {
break
}
}
if !has {
log.Error("apmSvc.moduleEdit have not module error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
}
var rls []*user.Rule
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&rls).Error; err != nil {
log.Error("apmSvc.ruleEdit modules error(%v)", err)
c.JSON(nil, err)
return
}
var (
ns []*user.Rule
ds []string
)
for _, m := range v.Rules {
if len(rls) == 0 {
ns = append(ns, &user.Rule{UserID: usr.ID, Rule: m})
continue
}
for j, rl := range rls {
if m == rl.Rule {
break
}
if j+1 == len(rls) {
ns = append(ns, &user.Rule{UserID: usr.ID, Rule: m})
}
}
}
for _, rl := range rls {
if len(v.Rules) == 0 {
ds = append(ds, rl.Rule)
continue
}
for j, m := range v.Rules {
if m == rl.Rule {
break
}
if j+1 == len(v.Rules) {
ds = append(ds, rl.Rule)
}
}
}
var sqlLogs []*map[string]interface{}
if err = apmSvc.DB.Exec("DELETE FROM user_rule WHERE user_id=? AND rule IN (?)", usr.ID, ds).Error; err != nil {
log.Error("apmSvc.ruleEdit delModule error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "delete",
"Where": "DELETE FROM user_rule WHERE user_id=? AND rule IN (?)",
"Value1": usr.ID,
"Value2": ds,
"Update": "",
"Old": "",
}
username := name(c)
sqlLogs = append(sqlLogs, sqlLog)
for _, n := range ns {
if err = apmSvc.DB.Create(n).Error; err != nil {
log.Error("apmSvc.ruleEdit addModule error(%v)", err)
c.JSON(nil, err)
apmSvc.SendLog(*c, username, 0, 2, 0, "apmSvc.ruleEdit", sqlLogs)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "add",
"Content": n,
}
sqlLogs = append(sqlLogs, sqlLog)
}
apmSvc.SendLog(*c, username, 0, 2, 0, "apmSvc.ruleEdit", sqlLogs)
c.JSON(nil, err)
}
func userSyncTree(c *bm.Context) {
username := name(c)
apmSvc.TreeSync(c, username, c.Request.Header.Get("Cookie"))
c.JSON(nil, nil)
}
func userTreeAppids(c *bm.Context) {
username := name(c)
appids, err := apmSvc.Appids(c, username, c.Request.Header.Get("Cookie"))
if err != nil {
log.Error("%v", err)
c.JSON(nil, err)
return
}
c.JSON(appids, nil)
}
func userTreeDiscovery(c *bm.Context) {
username := name(c)
appids, err := apmSvc.DiscoveryID(c, username, c.Request.Header.Get("Cookie"))
if err != nil {
log.Error("%v", err)
c.JSON(nil, err)
return
}
c.JSON(appids, nil)
}

View File

@@ -0,0 +1,87 @@
package http
import (
"context"
"encoding/json"
"flag"
"fmt"
"net/http"
"net/url"
"strings"
"testing"
"go-common/app/admin/main/apm/conf"
bm "go-common/library/net/http/blademaster"
. "github.com/smartystreets/goconvey/convey"
)
func TestUserRuleStates(t *testing.T) {
fmt.Println("========UserRuleStates tests========")
Convey("test userAuth", t, func() {
var params = url.Values{}
ctx := userRequest("GET", params)
userRuleStates(&ctx)
data, err := json.Marshal(ctx)
fmt.Println(string(data))
So(err, ShouldBeNil)
})
}
func TestUserApplies(t *testing.T) {
fmt.Println("========UserAppliestests========")
Convey("test userApplies", t, func() {
var params = url.Values{}
ctx := userRequest("GET", params)
userApplies(&ctx)
data, err := json.Marshal(ctx)
fmt.Println(string(data))
So(err, ShouldBeNil)
})
}
// func TestUserApply(t *testing.T) {
// fmt.Println("========UserApply tests========")
// Convey("test userApply", t, func() {
// var params = url.Values{}
// params.Set("item", "APP_AUTH_VIEW,APP_EDIT")
// ctx := userRequest("POST", params)
// userApply(&ctx)
// data, err := json.Marshal(ctx)
// fmt.Println(string(data))
// So(err, ShouldBeNil)
// })
// }
// func TestUserAudit(t *testing.T) {
// fmt.Println("========UserAudit tests========")
// Convey("test userAudit", t, func() {
// var params = url.Values{}
// params.Set("id", "2")
// params.Set("status", "2")
// ctx := userRequest("POST", params)
// userAudit(&ctx)
// data, err := json.Marshal(ctx)
// fmt.Println(string(data))
// So(err, ShouldBeNil)
// })
// }
func userRequest(method string, params url.Values) (ctx bm.Context) {
flag.Set("conf", "../cmd/apm-admin-test.toml")
conf.Init()
//apmSvc = service.New(conf.Conf)
path := "/"
req, _ := http.NewRequest(method, path, strings.NewReader(params.Encode()))
req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Cookie", "_AJSESSIONID=0eac92f0621b11e8b877522233007f8a; username=chengxing; sven-apm=fa7128be35363eb623e4dd5d611daf1f3273316cc09a66655db0e79f616d4f53")
req.ParseForm()
ctx = bm.Context{
Context: context.TODO(),
Request: req,
}
ctx.Set("username", "chengxing")
ctx.Request.ParseForm()
return
}

View File

@@ -0,0 +1,140 @@
package http
import (
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/ut"
saga "go-common/app/tool/saga/model"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
)
// @params ListReq
// @router get /x/admin/apm/ut/info/list
// @response Paper
func utList(c *bm.Context) {
var (
mrInfs []*ut.Merge
data *Paper
err error
count int
)
v := new(ut.MergeReq)
if err = c.Bind(v); err != nil {
return
}
if mrInfs, count, err = apmSvc.UtList(c, v); err != nil {
c.JSON(nil, err)
return
}
data = &Paper{
Total: count,
Pn: v.Pn,
Ps: v.Ps,
Items: mrInfs,
}
c.JSON(data, nil)
}
// @params DetailReq
// @router get /x/admin/apm/ut/detail/list
// @response PkgAnls
func utDetail(c *bm.Context) {
var (
utpkgs []*ut.PkgAnls
err error
)
v := new(ut.DetailReq)
if err = c.Bind(v); err != nil {
return
}
if utpkgs, err = apmSvc.UtDetailList(c, v); err != nil {
c.JSON(nil, err)
return
}
c.JSON(utpkgs, nil)
}
// @params HistoryCommitReq
// @router get /x/admin/apm/ut/history/commit
// @response Commit
func utHistoryCommit(c *bm.Context) {
var (
utcmts []*ut.Commit
count int
err error
data *Paper
)
v := new(ut.HistoryCommitReq)
if err = c.Bind(v); err != nil {
return
}
if utcmts, count, err = apmSvc.UtHistoryCommit(c, v); err != nil {
c.JSON(nil, err)
return
}
data = &Paper{
Total: count,
Pn: v.Pn,
Ps: v.Ps,
Items: utcmts,
}
c.JSON(data, nil)
}
func utBaseline(c *bm.Context) {
data := map[string]int{
"coverage": conf.Conf.UTBaseLine.Coverage,
"passrate": conf.Conf.UTBaseLine.Passrate,
}
c.JSON(data, nil)
}
// @params commit_id
// @router get /x/admin/apm/ut/check
// @response Tyrant
func check(c *bm.Context) {
var (
err error
ty *ut.Tyrant
res = new(struct {
CommitID string `form:"commit_id" validate:"required"`
})
)
if err = c.Bind(res); err != nil {
c.JSON(nil, err)
return
}
if ty, err = apmSvc.CheckUT(c, res.CommitID); err != nil {
c.JSON(nil, err)
return
}
c.JSON(ty, nil)
}
// @params merge_id
// @router get /x/admin/apm/ut/merge/set
// @response message
func utSetMerged(c *bm.Context) {
var (
err error
hookMR = &saga.HookMR{}
)
if err = c.BindWith(hookMR, binding.JSON); err != nil {
return
}
if hookMR.ObjectAttributes.State != "merged" {
c.JSON(nil, nil)
return
}
if err = apmSvc.SetMerged(c, hookMR.ObjectAttributes.IID); err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.WechatReport(c, hookMR.ObjectAttributes.IID, hookMR.ObjectAttributes.LastCommit.ID, hookMR.ObjectAttributes.SourceBranch, hookMR.ObjectAttributes.TargetBranch); err != nil {
c.JSON(nil, err)
return
}
c.JSONMap(map[string]interface{}{
"message": "单元测试is_merged更新成功",
}, nil)
}

View File

@@ -0,0 +1,30 @@
package http
import (
"go-common/app/admin/main/apm/model/ut"
bm "go-common/library/net/http/blademaster"
)
// utApps
func utApps(c *bm.Context) {
var (
err error
count int
res = []*ut.App{}
)
v := new(ut.AppReq)
if err = c.Bind(v); err != nil {
return
}
if res, count, err = apmSvc.UTApps(c, v); err != nil {
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: res,
Total: count,
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,185 @@
package http
import (
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/ut"
bm "go-common/library/net/http/blademaster"
)
// @params PCurveReq
// @router get /x/admin/apm/ut/dashboard/pcurve
// @response PCurveResp
func utDashCurve(c *bm.Context) {
var (
curve []*ut.PCurveResp
err error
)
v := new(ut.PCurveReq)
if err = c.Bind(v); err != nil {
return
}
if curve, err = apmSvc.DashCurveGraph(c, name(c), v); err != nil {
c.JSON(nil, err)
return
}
c.JSON(curve, nil)
}
// @params PCurveReq
// @router get /x/admin/apm/ut/dashboard/histogram
// @response PCurveDetailResp
func utDashHistogram(c *bm.Context) {
var (
histogram []*ut.PCurveDetailResp
err error
)
v := new(ut.PCurveReq)
if err = c.Bind(v); err != nil {
return
}
if histogram, err = apmSvc.DashGraphDetail(c, name(c), v); err != nil {
c.JSON(nil, err)
return
}
c.JSON(histogram, nil)
}
// @params PCurveReq
// @router get /x/admin/apm/ut/dashboard/user/detail
// @response PCurveDetailResp
func utDashUserDetail(c *bm.Context) {
var (
detail []*ut.PCurveDetailResp
err error
)
v := new(ut.PCurveReq)
if err = c.Bind(v); err != nil {
return
}
if detail, err = apmSvc.DashGraphDetailSingle(c, name(c), v); err != nil {
c.JSON(nil, err)
return
}
c.JSON(detail, nil)
}
// @params QATrendReq
// @router get /x/admin/apm/ut/quality/trend
// @response QATrendResp
func utQATrend(c *bm.Context) {
var (
trend *ut.QATrendResp
err error
)
v := new(ut.QATrendReq)
if err = c.Bind(v); err != nil {
return
}
if trend, err = apmSvc.QATrend(c, v); err != nil {
c.JSON(nil, err)
return
}
c.JSON(trend, nil)
}
// @params commits
// @router get /x/admin/apm/ut/commits
// @response CommitInfo
func utGeneralCommit(c *bm.Context) {
var (
cmInfos []*ut.CommitInfo
err error
)
v := new(struct {
Commits string `form:"commits"`
})
if err = c.Bind(v); err != nil {
return
}
if cmInfos, err = apmSvc.UTGernalCommit(c, v.Commits); err != nil {
c.JSON(nil, err)
return
}
c.JSON(cmInfos, nil)
}
// @params pkg
// @router get /x/admin/apm/ut/dashboard/pkgs
// @response []*ut.PkgAnls
func utDashPkgsTree(c *bm.Context) {
var (
err error
pkgs []*ut.PkgAnls
username = name(c)
req = new(struct {
PKG string `form:"pkg"`
})
)
if err = c.Bind(req); err != nil {
c.JSON(nil, err)
return
}
if pkgs, err = apmSvc.DashPkgsTree(c, req.PKG, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(pkgs, nil)
}
// @params project_id,merge_id,commit_id
// @router get /x/admin/apm/ut/git/report
// @response EmptyResp
func utGitReport(c *bm.Context) {
var (
err error
req = new(struct {
ProjectID int `form:"project_id" validate:"required"`
MergeID int `form:"merge_id" validate:"required"`
CommitID string `form:"commit_id" validate:"required"`
})
)
if err = c.Bind(req); err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.GitReport(c, req.ProjectID, req.MergeID, req.CommitID); err != nil {
c.JSON(nil, err)
return
}
}
// @params username,times
// @router get /x/admin/apm/ut/dashboard/history/commit
// @response []*ut.PkgAnls
func dashHistoryCommit(c *bm.Context) {
var (
err error
pkgs = make([]*ut.PkgAnls, 0)
req = new(struct {
UserName string `form:"user_name" default:""`
Times int64 `form:"times" default:"10"`
})
)
if err = c.Bind(req); err != nil {
c.JSON(nil, err)
return
}
if req.UserName == "" {
req.UserName = name(c)
}
if pkgs, err = apmSvc.CommitHistory(c, req.UserName, req.Times); err != nil {
c.JSON(nil, err)
return
}
data := new(struct {
Pkgs []*ut.PkgAnls `json:"pkgs"`
BaseLine struct {
Coverage int `json:"coverage"`
PassRate int `json:"pass_rate"`
} `json:"base_line"`
})
data.Pkgs = pkgs
data.BaseLine.Coverage = conf.Conf.UTBaseLine.Coverage
data.BaseLine.PassRate = conf.Conf.UTBaseLine.Passrate
c.JSON(data, nil)
}