You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
287 lines
8.1 KiB
287 lines
8.1 KiB
package service |
|
|
|
import ( |
|
"context" |
|
"encoding/json" |
|
"fmt" |
|
"net/http" |
|
"strings" |
|
"time" |
|
|
|
"go-common/app/admin/main/apm/conf" |
|
"go-common/app/admin/main/apm/model/tree" |
|
"go-common/library/ecode" |
|
"go-common/library/log" |
|
) |
|
|
|
const ( |
|
_discoveryIDKey = "%s_discoveryIDKey" |
|
) |
|
|
|
// Appids get appid by username. |
|
func (s *Service) Appids(c context.Context, username, cookie string) (appids []string, err error) { |
|
s.treeLock.RLock() |
|
nodem, ok := s.treeCache[username] |
|
tmp := make(map[string]struct{}) |
|
if !ok { |
|
s.treeLock.RUnlock() |
|
s.TreeSync(c, username, cookie) |
|
s.treeLock.RLock() |
|
nodem = s.treeCache[username] |
|
} |
|
for _, v := range nodem { |
|
nameArr := strings.Split(v.Path, ".") |
|
newName := nameArr[1] + "." + nameArr[2] + "." + nameArr[3] |
|
if _, ok := tmp[newName]; !ok { |
|
appids = append(appids, newName) |
|
tmp[newName] = struct{}{} |
|
} |
|
} |
|
s.treeLock.RUnlock() |
|
return |
|
} |
|
|
|
// Projects get projects by username. |
|
func (s *Service) Projects(c context.Context, username, cookie string) (projects []string, err error) { |
|
s.treeLock.RLock() |
|
nodem, ok := s.treeCache[username] |
|
mm := make(map[string]struct{}) |
|
if !ok { |
|
s.treeLock.RUnlock() |
|
s.TreeSync(c, username, cookie) |
|
s.treeLock.RLock() |
|
nodem = s.treeCache[username] |
|
} |
|
for _, v := range nodem { |
|
nameArr := strings.Split(v.Path, ".") |
|
newName := nameArr[1] + "." + nameArr[2] |
|
if _, ok := mm[newName]; ok { |
|
continue |
|
} |
|
mm[newName] = struct{}{} |
|
projects = append(projects, newName) |
|
} |
|
s.treeLock.RUnlock() |
|
return |
|
} |
|
|
|
// TreeSync sync tree cache by username. |
|
func (s *Service) TreeSync(c context.Context, username, cookie string) { |
|
nodem, err := s.roleTrees(c, username, cookie) |
|
if err != nil { |
|
log.Error("TreeSync(%s) error(%v)", username, err) |
|
return |
|
} |
|
s.treeLock.Lock() |
|
s.treeCache[username] = nodem |
|
s.treeLock.Unlock() |
|
} |
|
|
|
// trees get service trees by username. |
|
func (s *Service) roleTrees(c context.Context, username, cookie string) (trees []*tree.Node, err error) { |
|
url := "http://easyst.bilibili.co/v1/auth" |
|
req, err := http.NewRequest("GET", url, nil) |
|
if err != nil { |
|
err = ecode.RequestErr |
|
return |
|
} |
|
req.Header.Set("Content-Type", "application/json;charset=UTF-8") |
|
req.Header.Set("Cookie", cookie) |
|
var result = &tree.TokenResult{} |
|
if err = s.client.Do(c, req, result); err != nil { |
|
log.Error("TreeSync(%s) error(%v)", username, err) |
|
err = ecode.RequestErr |
|
return |
|
} |
|
|
|
url = "http://easyst.bilibili.co/v1/node/role/app" |
|
if req, err = http.NewRequest("GET", url, nil); err != nil { |
|
log.Error("TreeSync(%s) get token error(%v)", username, err) |
|
err = ecode.RequestErr |
|
return |
|
} |
|
req.Header.Set("Content-Type", "application/json") |
|
req.Header.Set("X-Authorization-Token", result.Data.Token) |
|
var dat = &tree.Resp{} |
|
if err = s.client.Do(c, req, dat); err != nil { |
|
log.Error("TreeSync(%s) token(%s) error(%v)", username, result.Data.Token, err) |
|
err = ecode.RequestErr |
|
return |
|
} |
|
if len(dat.Data) == 0 { |
|
log.Error("TreeSync(%s) no data", username) |
|
return |
|
} |
|
trees = dat.Data |
|
log.Info("TreeSync(%s) data(%v)", username, trees) |
|
return |
|
} |
|
|
|
// Trees tree list |
|
func (s *Service) Trees(c context.Context, username, cookie string) (nodem []*tree.Node, err error) { |
|
s.treeLock.RLock() |
|
nodem, ok := s.treeCache[username] |
|
if !ok { |
|
s.treeLock.RUnlock() |
|
s.TreeSync(c, username, cookie) |
|
s.treeLock.RLock() |
|
nodem = s.treeCache[username] |
|
} |
|
s.treeLock.RUnlock() |
|
return |
|
} |
|
|
|
// AllTrees AllTrees |
|
// func (s *Service) AllTrees(c context.Context, username, cookie string) (trees []*tree.Info, err error) { |
|
// var ( |
|
// jsonBytes []byte |
|
// url = "http://easyst.bilibili.co/v1/token" |
|
// ) |
|
// body := &struct { |
|
// Username string `json:"user_name"` |
|
// PlatformID string `json:"platform_id"` |
|
// }{ |
|
// Username: "main", |
|
// PlatformID: conf.Conf.Tree.PlatformID, |
|
// } |
|
// if jsonBytes, err = json.Marshal(body); err != nil { |
|
// log.Error("json.Marshal(body) error(%v)", err) |
|
// return |
|
// } |
|
// req, err := http.NewRequest("POST", url, strings.NewReader(string(jsonBytes))) |
|
// if err != nil { |
|
// log.Error("http.NewRequest failed", err) |
|
// return |
|
// } |
|
// req.Header.Set("Content-Type", "application/json") |
|
// result := &struct { |
|
// Code int `json:"code"` |
|
// Data *model.ServiceTreeToken `json:"data"` |
|
// Message string `json:"message"` |
|
// Status int `json:"status"` |
|
// }{} |
|
// if err = s.client.Do(c, req, result); err != nil { |
|
// log.Error("TreesAll(%s) get token error(%v)", username, err) |
|
// err = ecode.RequestErr |
|
// return |
|
// } |
|
// url = "http://easyst.bilibili.co/v1/node/app/extendinfo" |
|
// if req, err = http.NewRequest("GET", url, nil); err != nil { |
|
// log.Error("TreesAll(%s) error(%v)", username, err) |
|
// err = ecode.RequestErr |
|
// return |
|
// } |
|
// req.Header.Set("Content-Type", "application/json") |
|
// req.Header.Set("X-Authorization-Token", result.Data.Token) |
|
// var dat = &tree.Rest{} |
|
// if err = s.client.Do(c, req, dat); err != nil { |
|
// log.Error("TreesAll(%s) token(%s) error(%v)", username, result.Data.Token, err) |
|
// err = ecode.RequestErr |
|
// return |
|
// } |
|
// if len(dat.Data) == 0 { |
|
// log.Error("TreesAll(%s) no data", username) |
|
// return |
|
// } |
|
// trees = dat.Data |
|
// log.Info("TreesAll(%s) data(%v)", username, trees) |
|
// return |
|
// } |
|
|
|
// DiscoveryID get appid by username. |
|
func (s *Service) DiscoveryID(c context.Context, username, cookie string) (appids []string, err error) { |
|
keyName := discoveryIDKey(username) |
|
s.discoveryIDLock.RLock() |
|
nodem, ok := s.discoveryIDCache[keyName] |
|
if !ok || (time.Since(nodem.CTime) > 60*time.Second) { |
|
s.discoveryIDLock.RUnlock() |
|
s.DiscoveryTreeSync(c, username, cookie) |
|
s.discoveryIDLock.RLock() |
|
nodem = s.discoveryIDCache[keyName] |
|
} |
|
s.discoveryIDLock.RUnlock() |
|
tmp := make(map[string]struct{}) |
|
for _, v := range nodem.Data { |
|
var newName string |
|
if v.DiscoveryID != "" { |
|
newName = v.DiscoveryID |
|
} else { |
|
nameArr := strings.Split(v.AppID, ".") |
|
newName = nameArr[0] + "." + nameArr[1] + "." + nameArr[2] |
|
} |
|
if _, ok := tmp[newName]; !ok { |
|
appids = append(appids, newName) |
|
tmp[newName] = struct{}{} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// discoveryAllTrees ... |
|
func (s *Service) discoveryAllTrees(c context.Context, username, cookie string) (dat *tree.Resd, err error) { |
|
url := "http://easyst.bilibili.co/v1/token" |
|
var jsonBytes []byte |
|
body := &struct { |
|
Username string `json:"user_name"` |
|
PlatformID string `json:"platform_id"` |
|
}{ |
|
Username: "msm", |
|
PlatformID: conf.Conf.Tree.MsmPlatformID, |
|
} |
|
if jsonBytes, err = json.Marshal(body); err != nil { |
|
log.Error("json.Marshal(body) error(%v)", err) |
|
return |
|
} |
|
req, err := http.NewRequest("POST", url, strings.NewReader(string(jsonBytes))) |
|
if err != nil { |
|
err = ecode.RequestErr |
|
return |
|
} |
|
req.Header.Set("Content-Type", "application/json;charset=UTF-8") |
|
req.Header.Set("Cookie", cookie) |
|
var result = &tree.TokenResult{} |
|
if err = s.client.Do(c, req, result); err != nil { |
|
log.Error("TreeSync(%s) error(%v)", username, err) |
|
err = ecode.RequestErr |
|
return |
|
} |
|
dat = &tree.Resd{} |
|
url = "http://easyst.bilibili.co/v1/node/app/secretinfo/prod" |
|
if req, err = http.NewRequest("GET", url, nil); err != nil { |
|
log.Error("TreeSync(%s) get token error(%v)", username, err) |
|
err = ecode.RequestErr |
|
return |
|
} |
|
req.Header.Set("Content-Type", "application/json") |
|
req.Header.Set("X-Authorization-Token", result.Data.Token) |
|
if err = s.client.Do(c, req, dat); err != nil { |
|
log.Error("TreeSync(%s) token(%s) error(%v)", username, result.Data.Token, err) |
|
err = ecode.RequestErr |
|
return |
|
} |
|
if len(dat.Data) == 0 { |
|
log.Error("TreeSync(%s) no data", username) |
|
return |
|
} |
|
dat.CTime = time.Now() |
|
log.Info("TreeSync(%s) data(%v)", username, dat) |
|
return |
|
} |
|
|
|
func discoveryIDKey(username string) string { |
|
return fmt.Sprintf(_discoveryIDKey, username) |
|
} |
|
|
|
// DiscoveryTreeSync sync tree cache by username discoverykey. |
|
func (s *Service) DiscoveryTreeSync(c context.Context, username, cookie string) { |
|
keyName := discoveryIDKey(username) |
|
nodem, err := s.discoveryAllTrees(c, username, cookie) |
|
if err != nil { |
|
log.Error("DiscoveryTreeSync(%s) error(%v)", username, err) |
|
return |
|
} |
|
|
|
s.discoveryIDLock.Lock() |
|
s.discoveryIDCache[keyName] = nodem |
|
s.discoveryIDLock.Unlock() |
|
}
|
|
|