package models import ( "encoding/json" "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/rands" "github.com/iwind/TeaGo/types" "time" ) const ( HTTPDNSNodeStateEnabled = 1 // 已启用 HTTPDNSNodeStateDisabled = 0 // 已禁用 ) type HTTPDNSNodeDAO dbs.DAO func NewHTTPDNSNodeDAO() *HTTPDNSNodeDAO { return dbs.NewDAO(&HTTPDNSNodeDAO{ DAOObject: dbs.DAOObject{ DB: Tea.Env, Table: "edgeHTTPDNSNodes", Model: new(HTTPDNSNode), PkName: "id", }, }).(*HTTPDNSNodeDAO) } var SharedHTTPDNSNodeDAO *HTTPDNSNodeDAO func init() { dbs.OnReady(func() { SharedHTTPDNSNodeDAO = NewHTTPDNSNodeDAO() }) } // FindEnabledNodeIdWithUniqueId 根据唯一ID获取启用中的HTTPDNS节点ID func (this *HTTPDNSNodeDAO) FindEnabledNodeIdWithUniqueId(tx *dbs.Tx, uniqueId string) (int64, error) { return this.Query(tx). Attr("uniqueId", uniqueId). Attr("state", HTTPDNSNodeStateEnabled). ResultPk(). FindInt64Col(0) } // CreateNode 创建节点 func (this *HTTPDNSNodeDAO) CreateNode(tx *dbs.Tx, clusterId int64, name string, installDir string, isOn bool) (int64, error) { uniqueId := rands.HexString(32) secret := rands.String(32) err := SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleHTTPDNS) if err != nil { return 0, err } var op = NewHTTPDNSNodeOperator() op.ClusterId = clusterId op.Name = name op.IsOn = isOn op.IsUp = false op.IsInstalled = false op.IsActive = false op.UniqueId = uniqueId op.Secret = secret op.InstallDir = installDir op.CreatedAt = time.Now().Unix() op.UpdatedAt = time.Now().Unix() op.State = HTTPDNSNodeStateEnabled err = this.Save(tx, op) if err != nil { return 0, err } return types.Int64(op.Id), nil } // UpdateNode 更新节点 func (this *HTTPDNSNodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, name string, installDir string, isOn bool) error { var op = NewHTTPDNSNodeOperator() op.Id = nodeId op.Name = name op.InstallDir = installDir op.IsOn = isOn op.UpdatedAt = time.Now().Unix() return this.Save(tx, op) } // DisableNode 禁用节点 func (this *HTTPDNSNodeDAO) DisableNode(tx *dbs.Tx, nodeId int64) error { node, err := this.FindEnabledNode(tx, nodeId) if err != nil { return err } if node == nil { return nil } _, err = this.Query(tx). Pk(nodeId). Set("state", HTTPDNSNodeStateDisabled). Update() if err != nil { return err } _, err = SharedApiTokenDAO.Query(tx). Attr("nodeId", node.UniqueId). Attr("role", nodeconfigs.NodeRoleHTTPDNS). Set("state", ApiTokenStateDisabled). Update() return err } // FindEnabledNode 查找启用节点 func (this *HTTPDNSNodeDAO) FindEnabledNode(tx *dbs.Tx, nodeId int64) (*HTTPDNSNode, error) { one, err := this.Query(tx). Pk(nodeId). Attr("state", HTTPDNSNodeStateEnabled). Find() if one == nil { return nil, err } return one.(*HTTPDNSNode), nil } // FindNodeClusterId 查询节点所属集群ID func (this *HTTPDNSNodeDAO) FindNodeClusterId(tx *dbs.Tx, nodeId int64) (int64, error) { return this.Query(tx). Pk(nodeId). Attr("state", HTTPDNSNodeStateEnabled). Result("clusterId"). FindInt64Col(0) } // ListEnabledNodes 列出节点 func (this *HTTPDNSNodeDAO) ListEnabledNodes(tx *dbs.Tx, clusterId int64) (result []*HTTPDNSNode, err error) { query := this.Query(tx). State(HTTPDNSNodeStateEnabled). AscPk() if clusterId > 0 { query = query.Attr("clusterId", clusterId) } _, err = query.Slice(&result).FindAll() return } // UpdateNodeStatus 更新节点状态 func (this *HTTPDNSNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, isUp bool, isInstalled bool, isActive bool, statusJSON []byte, installStatusJSON []byte) error { var op = NewHTTPDNSNodeOperator() op.Id = nodeId op.IsUp = isUp op.IsInstalled = isInstalled op.IsActive = isActive op.UpdatedAt = time.Now().Unix() if len(statusJSON) > 0 { op.Status = statusJSON } if len(installStatusJSON) > 0 { mergedStatusJSON, mergeErr := this.mergeInstallStatusJSON(tx, nodeId, installStatusJSON) if mergeErr != nil { return mergeErr } op.InstallStatus = mergedStatusJSON } return this.Save(tx, op) } // UpdateNodeInstallStatus 更新节点安装状态 func (this *HTTPDNSNodeDAO) UpdateNodeInstallStatus(tx *dbs.Tx, nodeId int64, installStatus *NodeInstallStatus) error { if installStatus == nil { return nil } // Read existing installStatus to preserve custom fields like 'ssh' and 'ipAddr' raw, err := this.Query(tx).Pk(nodeId).Result("installStatus").FindBytesCol() if err != nil { return err } var m = map[string]interface{}{} if len(raw) > 0 { _ = json.Unmarshal(raw, &m) } // Overlay standard install status fields statusData, err := json.Marshal(installStatus) if err != nil { return err } var newStatusMap = map[string]interface{}{} _ = json.Unmarshal(statusData, &newStatusMap) for k, v := range newStatusMap { m[k] = v } // Re-marshal the merged map mergedData, err := json.Marshal(m) if err != nil { return err } _, err = this.Query(tx). Pk(nodeId). Set("installStatus", mergedData). Set("updatedAt", time.Now().Unix()). Update() return err } func (this *HTTPDNSNodeDAO) mergeInstallStatusJSON(tx *dbs.Tx, nodeId int64, patch []byte) ([]byte, error) { if len(patch) == 0 { return patch, nil } raw, err := this.Query(tx).Pk(nodeId).Result("installStatus").FindBytesCol() if err != nil { return nil, err } merged := map[string]interface{}{} if len(raw) > 0 { _ = json.Unmarshal(raw, &merged) } patchMap := map[string]interface{}{} if len(patch) > 0 { _ = json.Unmarshal(patch, &patchMap) } for k, v := range patchMap { merged[k] = v } data, err := json.Marshal(merged) if err != nil { return nil, err } return data, nil } // FindNodeInstallStatus 读取节点安装状态 func (this *HTTPDNSNodeDAO) FindNodeInstallStatus(tx *dbs.Tx, nodeId int64) (*NodeInstallStatus, error) { raw, err := this.Query(tx). Pk(nodeId). State(HTTPDNSNodeStateEnabled). Result("installStatus"). FindBytesCol() if err != nil { return nil, err } if len(raw) == 0 { return nil, nil } installStatus := &NodeInstallStatus{} err = json.Unmarshal(raw, installStatus) if err != nil { return nil, err } return installStatus, nil } // UpdateNodeIsInstalled 更新节点安装状态位 func (this *HTTPDNSNodeDAO) UpdateNodeIsInstalled(tx *dbs.Tx, nodeId int64, isInstalled bool) error { _, err := this.Query(tx). Pk(nodeId). State(HTTPDNSNodeStateEnabled). Set("isInstalled", isInstalled). Set("updatedAt", time.Now().Unix()). Update() return err }