tree.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. package dao
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "net/http"
  7. "go-common/app/admin/ep/merlin/model"
  8. "go-common/library/cache/memcache"
  9. "go-common/library/ecode"
  10. "go-common/library/log"
  11. )
  12. const (
  13. _treeURI = "/v1/node/tree"
  14. _treeMachines = "/v1/instance/hostnames"
  15. _treeSon = "/v1/node/extree"
  16. _treeRole = "/v1/node/role"
  17. _treeAppInstance = "/v1/instance/app"
  18. _authURI = "/v1/auth"
  19. _authPlatformURI = "/v1/token"
  20. _treeOkCode = 90000
  21. _sessIDKey = "_AJSESSIONID"
  22. _treeRootName = "bilibili."
  23. _questionMark = "?"
  24. )
  25. // UserTree get user tree node.
  26. func (d *Dao) UserTree(c context.Context, sessionID string) (tree *model.UserTree, err error) {
  27. var (
  28. req *http.Request
  29. res = &model.TreeResponse{}
  30. )
  31. if req, err = d.newTreeRequest(c, http.MethodGet, _treeURI, sessionID, nil); err != nil {
  32. return
  33. }
  34. if err = d.httpClient.Do(c, req, &res); err != nil {
  35. log.Error("d.Token url(%s) err(%v)", _treeURI, err)
  36. err = ecode.MerlinTreeRequestErr
  37. return
  38. }
  39. if res.Code != _treeOkCode {
  40. err = fmt.Errorf("error code :%d", res.Code)
  41. log.Error("Status url(%s) res(%v)", _treeURI, res)
  42. return
  43. }
  44. tree = &res.Data
  45. return
  46. }
  47. // TreeSon get user tree node son node.
  48. func (d *Dao) TreeSon(c context.Context, sessionID, treePath string) (treeSon map[string]interface{}, err error) {
  49. var (
  50. req *http.Request
  51. res = &model.TreeSonResponse{}
  52. )
  53. if req, err = d.newTreeRequest(c, http.MethodGet, _treeSon+"/"+d.getTreeFullPath(treePath), sessionID, nil); err != nil {
  54. return
  55. }
  56. if err = d.httpClient.Do(c, req, &res); err != nil {
  57. log.Error("d.Token url(%s) err(%v)", _treeSon, err)
  58. err = ecode.MerlinTreeRequestErr
  59. return
  60. }
  61. if res.Code != _treeOkCode {
  62. err = fmt.Errorf("error code :%d", res.Code)
  63. log.Error("Status url(%s) res(%v)", _treeSon, res)
  64. return
  65. }
  66. return res.Data, nil
  67. }
  68. // TreeRoles get tree roles.
  69. func (d *Dao) TreeRoles(c context.Context, sessionID, treePath string) (treeRoles []*model.TreeRole, err error) {
  70. var (
  71. req *http.Request
  72. res = &model.TreeRoleResponse{}
  73. )
  74. if req, err = d.newTreeRequest(c, http.MethodGet, _treeRole+"/"+d.getTreeFullPath(treePath), sessionID, nil); err != nil {
  75. return
  76. }
  77. if err = d.httpClient.Do(c, req, &res); err != nil {
  78. log.Error("d.Token url(%s) err(%v)", _treeRole, err)
  79. err = ecode.MerlinTreeRequestErr
  80. return
  81. }
  82. if res.Code != _treeOkCode {
  83. err = fmt.Errorf("error code :%d", res.Code)
  84. log.Error("Status url(%s) res(%v)", _treeRole, res)
  85. return
  86. }
  87. return res.Data, nil
  88. }
  89. // TreeRolesAsPlatform get tree roles.
  90. func (d *Dao) TreeRolesAsPlatform(c context.Context, treePath string) (treeRoles []*model.TreeRole, err error) {
  91. var (
  92. req *http.Request
  93. res = &model.TreeRoleResponse{}
  94. )
  95. if req, err = d.newPlatformTreeRequest(c, http.MethodGet, _treeRole+"/"+d.getTreeFullPath(treePath), nil); err != nil {
  96. return
  97. }
  98. if err = d.httpClient.Do(c, req, &res); err != nil {
  99. log.Error("d.Token url(%s) err(%v)", _treeRole, err)
  100. err = ecode.MerlinTreeRequestErr
  101. return
  102. }
  103. if res.Code != _treeOkCode {
  104. err = fmt.Errorf("error code :%d", res.Code)
  105. log.Error("Status url(%s) res(%v)", _treeRole, res)
  106. return
  107. }
  108. return res.Data, nil
  109. }
  110. //QueryTreeInstances query tree instances
  111. func (d *Dao) QueryTreeInstances(c context.Context, sessionID string, tir *model.TreeInstanceRequest) (tid map[string]*model.TreeInstance, err error) {
  112. var (
  113. req *http.Request
  114. res = &model.TreeInstancesResponse{}
  115. )
  116. if req, err = d.newTreeRequest(c, http.MethodGet, _treeMachines+_questionMark+tir.ToQueryURI(), sessionID, nil); err != nil {
  117. return
  118. }
  119. if err = d.httpClient.Do(c, req, &res); err != nil {
  120. log.Error("d.Token url(%s) err(%v)", _treeRole, err)
  121. err = ecode.MerlinTreeRequestErr
  122. return
  123. }
  124. if res.Code != _treeOkCode {
  125. log.Error("Status url(%s) res(%v)", _treeRole, res)
  126. err = ecode.MerlinTreeResponseErr
  127. return
  128. }
  129. tid = res.Data
  130. return
  131. }
  132. // TreeAppInstance get user tree node app instance.
  133. func (d *Dao) TreeAppInstance(c context.Context, treePaths []string) (treeAppInstances map[string][]*model.TreeAppInstance, err error) {
  134. var (
  135. req *http.Request
  136. res = &model.TreeAppInstanceResponse{}
  137. fullTreePaths []string
  138. )
  139. for _, treePath := range treePaths {
  140. fullTreePaths = append(fullTreePaths, d.getTreeFullPath(treePath))
  141. }
  142. treeAppInstanceRequest := &model.TreeAppInstanceRequest{
  143. Paths: fullTreePaths,
  144. }
  145. if req, err = d.newPlatformTreeRequest(c, http.MethodPost, _treeAppInstance+"?type=container", treeAppInstanceRequest); err != nil {
  146. return
  147. }
  148. if err = d.httpClient.Do(c, req, &res); err != nil {
  149. log.Error("d.Token url(%s) err(%v)", _treeRole, err)
  150. err = ecode.MerlinTreeRequestErr
  151. return
  152. }
  153. if res.Code != _treeOkCode {
  154. err = fmt.Errorf("error code :%d", res.Code)
  155. log.Error("Status url(%s) res(%v)", _treeRole, res)
  156. return
  157. }
  158. return res.Data, nil
  159. }
  160. func (d *Dao) treeToken(c context.Context, sessionID string) (authToken string, err error) {
  161. var (
  162. conn = d.mc.Get(c)
  163. item *memcache.Item
  164. )
  165. defer conn.Close()
  166. if item, err = conn.Get(sessionID); err == nil {
  167. if err = json.Unmarshal(item.Value, &authToken); err != nil {
  168. log.Error("treePlatformToken json parse error(%v)", err)
  169. }
  170. return
  171. }
  172. if authToken, err = d.authTree(c, sessionID); err != nil {
  173. return
  174. }
  175. item = &memcache.Item{Key: sessionID, Object: authToken, Flags: memcache.FlagJSON, Expiration: d.expire}
  176. d.tokenCacheSave(c, item)
  177. return
  178. }
  179. func (d *Dao) authTree(c context.Context, sessionID string) (authToken string, err error) {
  180. var (
  181. req *http.Request
  182. tokenURL = d.c.ServiceTree.Host + _authURI
  183. res struct {
  184. Code int `json:"code"`
  185. Data map[string]interface{} `json:"data"`
  186. Message string `json:"message"`
  187. Status int `json:"status"`
  188. }
  189. )
  190. if req, err = d.newRequest(http.MethodGet, tokenURL, nil); err != nil {
  191. return
  192. }
  193. req.Header.Set("Cookie", _sessIDKey+"="+sessionID)
  194. if err = d.httpClient.Do(c, req, &res); err != nil {
  195. err = ecode.MerlinTreeRequestErr
  196. log.Error("d.Token url(%s) res($s) err(%v)", tokenURL, res, err)
  197. return
  198. }
  199. if res.Code != _treeOkCode {
  200. log.Error("Status url(%s) res(%v)", tokenURL, res)
  201. return
  202. }
  203. authToken = res.Data["token"].(string)
  204. return
  205. }
  206. func (d *Dao) newTreeRequest(c context.Context, method, uri, sessionID string, v interface{}) (req *http.Request, err error) {
  207. var authToken string
  208. if authToken, err = d.treeToken(c, sessionID); err != nil {
  209. return
  210. }
  211. if req, err = d.newRequest(method, d.c.ServiceTree.Host+uri, v); err != nil {
  212. return
  213. }
  214. req.Header.Set(_authHeader, authToken)
  215. return
  216. }
  217. func (d *Dao) treePlatformToken(c context.Context) (authToken string, err error) {
  218. var (
  219. conn = d.mc.Get(c)
  220. item *memcache.Item
  221. username = d.c.ServiceTree.Key
  222. secret = d.c.ServiceTree.Secret
  223. )
  224. defer conn.Close()
  225. if item, err = conn.Get(secret); err == nil {
  226. if err = json.Unmarshal(item.Value, &authToken); err != nil {
  227. log.Error("treePlatformToken json parse error(%v)", err)
  228. }
  229. return
  230. }
  231. if authToken, err = d.authPlatformTree(c, username, secret); err != nil {
  232. return
  233. }
  234. item = &memcache.Item{Key: secret, Object: authToken, Flags: memcache.FlagJSON, Expiration: d.expire}
  235. d.tokenCacheSave(c, item)
  236. return
  237. }
  238. func (d *Dao) authPlatformTree(c context.Context, username, platformID string) (authToken string, err error) {
  239. var (
  240. req *http.Request
  241. tokenURL = d.c.ServiceTree.Host + _authPlatformURI
  242. res struct {
  243. Code int `json:"code"`
  244. Data map[string]interface{} `json:"data"`
  245. Message string `json:"message"`
  246. Status int `json:"status"`
  247. }
  248. )
  249. treePlatformTokenRequest := &model.TreePlatformTokenRequest{
  250. UserName: username,
  251. PlatformID: platformID,
  252. }
  253. if req, err = d.newRequest(http.MethodPost, tokenURL, treePlatformTokenRequest); err != nil {
  254. return
  255. }
  256. if err = d.httpClient.Do(c, req, &res); err != nil {
  257. err = ecode.MerlinTreeRequestErr
  258. log.Error("d.Token url(%s) res($s) err(%v)", tokenURL, res, err)
  259. return
  260. }
  261. if res.Code != _treeOkCode {
  262. log.Error("Status url(%s) res(%v)", tokenURL, res)
  263. return
  264. }
  265. authToken = res.Data["token"].(string)
  266. return
  267. }
  268. func (d *Dao) newPlatformTreeRequest(c context.Context, method, uri string, v interface{}) (req *http.Request, err error) {
  269. var authToken string
  270. if authToken, err = d.treePlatformToken(c); err != nil {
  271. return
  272. }
  273. if req, err = d.newRequest(method, d.c.ServiceTree.Host+uri, v); err != nil {
  274. return
  275. }
  276. req.Header.Set(_authHeader, authToken)
  277. return
  278. }
  279. func (d *Dao) getTreeFullPath(path string) string {
  280. return _treeRootName + path
  281. }