From a9d6d6f820cc4f00aa8286e317952cc1708639e1 Mon Sep 17 00:00:00 2001 From: Paul Chu Date: Fri, 7 May 2021 11:10:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=8A=82=E7=82=B9=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=20(#680)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enable promethues summary * ADD: 添加节点迁移的方法 * FIX: node move session commit * ADD: 注册迁移节点的接口 * MOD: fix error handle Co-authored-by: zhupeiyuan --- src/models/node.go | 48 ++++++++++++++++++++++++++ src/modules/server/http/router.go | 1 + src/modules/server/http/router_node.go | 18 ++++++++++ 3 files changed, 67 insertions(+) diff --git a/src/models/node.go b/src/models/node.go index a0148094..4bcbbfe4 100644 --- a/src/models/node.go +++ b/src/models/node.go @@ -321,6 +321,54 @@ func (n *Node) Modify(name, cate, note string, adminIds []int64) error { return session.Commit() } +func (n *Node) Move(tnode *Node) error { + // 检查是否属于同一个租户,不同租户的节点迁移需要迁移机器,暂时不支持 + if n.Tenant() != tnode.Tenant() { + return fmt.Errorf("target node %s in diffrent tenant", tnode.Path) + } + + pathPrefix := n.Path + "." + // 检查迁移目标节点不能是待迁移节点的子孙节点 + if strings.HasPrefix(tnode.Path, pathPrefix) { + return fmt.Errorf("target node %s is descendant of %s", tnode.Path, n.Path) + } + + // 找出所有的子节点,需要修改 path + var children []*Node + if err := DB["rdb"].Where("path like ?", "%"+pathPrefix+".%").Find(&children); err != nil { + return err + } + + n.Pid = tnode.Id + n.Path = tnode.Path + "." + n.Ident + newPrefix := n.Path + "." + for _, child := range children { + child.Path = strings.Replace(child.Path, pathPrefix, newPrefix, 1) + } + + // 事物处理所有数据库 path 修改 + session := DB["rdb"].NewSession() + defer session.Close() + + if err := session.Begin(); err != nil { + return err + } + + if _, err := session.Where("id=?", n.Id).Cols("pid", "path").Update(n); err != nil { + session.Rollback() + return err + } + + for _, child := range children { + if _, err := session.Where("id=?", child.Id).Cols("path").Update(child); err != nil { + session.Rollback() + return err + } + } + + return session.Commit() +} + func (n *Node) Del() error { // inner 租户节点不允许删除 if n.Path == InnerTenantIdent { diff --git a/src/modules/server/http/router.go b/src/modules/server/http/router.go index ead998d4..247e80f9 100644 --- a/src/modules/server/http/router.go +++ b/src/modules/server/http/router.go @@ -139,6 +139,7 @@ func Config(r *gin.Engine) { rdbRootLogin.GET("/nodes/trash", nodeTrashGets) rdbRootLogin.PUT("/nodes/trash/recycle", nodeTrashRecycle) + rdbRootLogin.PATCH("/node/:id/move", nodeMove) rdbRootLogin.POST("/sso/clients", ssoClientsPost) rdbRootLogin.GET("/sso/clients", ssoClientsGet) diff --git a/src/modules/server/http/router_node.go b/src/modules/server/http/router_node.go index 7be3a2a9..6e93c88c 100644 --- a/src/modules/server/http/router_node.go +++ b/src/modules/server/http/router_node.go @@ -216,6 +216,24 @@ func nodePut(c *gin.Context) { renderData(c, node, err) } +func nodeMove(c *gin.Context) { + id := urlParamInt64(c, "id") + node := Node(id) + + loginUser(c).CheckPermByNode(node, "rdb_node_delete") + + var f struct { + Pid int64 `json:"pid"` + } + bind(c, &f) + tNode := Node(f.Pid) + + loginUser(c).CheckPermByNode(tNode, "rdb_node_create") + + err := node.Move(tNode) + renderData(c, node, err) +} + func nodeDel(c *gin.Context) { id := urlParamInt64(c, "id") node := Node(id)