diff --git a/internal/db/models/api_node_dao.go b/internal/db/models/api_node_dao.go index 8fd28f42..c51b705a 100644 --- a/internal/db/models/api_node_dao.go +++ b/internal/db/models/api_node_dao.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "github.com/TeaOSLab/EdgeAPI/internal/utils" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" @@ -97,7 +98,7 @@ func (this *APINodeDAO) CreateAPINode(tx *dbs.Tx, name string, description strin return 0, err } secret := rands.String(32) - err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, NodeRoleAPI) + err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleAPI) if err != nil { return } diff --git a/internal/db/models/api_token_dao.go b/internal/db/models/api_token_dao.go index b4d43827..ef063869 100644 --- a/internal/db/models/api_token_dao.go +++ b/internal/db/models/api_token_dao.go @@ -1,6 +1,7 @@ package models import ( + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" @@ -34,7 +35,7 @@ func init() { }) } -// 启用条目 +// EnableApiToken 启用条目 func (this *ApiTokenDAO) EnableApiToken(tx *dbs.Tx, id uint32) (rowsAffected int64, err error) { return this.Query(tx). Pk(id). @@ -42,7 +43,7 @@ func (this *ApiTokenDAO) EnableApiToken(tx *dbs.Tx, id uint32) (rowsAffected int Update() } -// 禁用条目 +// DisableApiToken 禁用条目 func (this *ApiTokenDAO) DisableApiToken(tx *dbs.Tx, id uint32) (rowsAffected int64, err error) { return this.Query(tx). Pk(id). @@ -50,7 +51,7 @@ func (this *ApiTokenDAO) DisableApiToken(tx *dbs.Tx, id uint32) (rowsAffected in Update() } -// 查找启用中的条目 +// FindEnabledApiToken 查找启用中的条目 func (this *ApiTokenDAO) FindEnabledApiToken(tx *dbs.Tx, id uint32) (*ApiToken, error) { result, err := this.Query(tx). Pk(id). @@ -62,7 +63,7 @@ func (this *ApiTokenDAO) FindEnabledApiToken(tx *dbs.Tx, id uint32) (*ApiToken, return result.(*ApiToken), err } -// 获取可缓存的节点Token信息 +// FindEnabledTokenWithNodeCacheable 获取可缓存的节点Token信息 func (this *ApiTokenDAO) FindEnabledTokenWithNodeCacheable(tx *dbs.Tx, nodeId string) (*ApiToken, error) { SharedCacheLocker.RLock() token, ok := apiTokenCacheMap[nodeId] @@ -85,7 +86,7 @@ func (this *ApiTokenDAO) FindEnabledTokenWithNodeCacheable(tx *dbs.Tx, nodeId st return nil, err } -// 获取节点Token信息并可以缓存 +// FindEnabledTokenWithNode 获取节点Token信息并可以缓存 func (this *ApiTokenDAO) FindEnabledTokenWithNode(tx *dbs.Tx, nodeId string) (*ApiToken, error) { one, err := this.Query(tx). Attr("nodeId", nodeId). @@ -97,7 +98,7 @@ func (this *ApiTokenDAO) FindEnabledTokenWithNode(tx *dbs.Tx, nodeId string) (*A return nil, err } -// 根据角色获取节点 +// FindEnabledTokenWithRole 根据角色获取节点 func (this *ApiTokenDAO) FindEnabledTokenWithRole(tx *dbs.Tx, role string) (*ApiToken, error) { one, err := this.Query(tx). Attr("role", role). @@ -109,8 +110,8 @@ func (this *ApiTokenDAO) FindEnabledTokenWithRole(tx *dbs.Tx, role string) (*Api return nil, err } -// 保存API Token -func (this *ApiTokenDAO) CreateAPIToken(tx *dbs.Tx, nodeId string, secret string, role NodeRole) error { +// CreateAPIToken 保存API Token +func (this *ApiTokenDAO) CreateAPIToken(tx *dbs.Tx, nodeId string, secret string, role nodeconfigs.NodeRole) error { op := NewApiTokenOperator() op.NodeId = nodeId op.Secret = secret diff --git a/internal/db/models/authority/authority_node_dao.go b/internal/db/models/authority/authority_node_dao.go index 37dea7a3..7280d62f 100644 --- a/internal/db/models/authority/authority_node_dao.go +++ b/internal/db/models/authority/authority_node_dao.go @@ -4,6 +4,7 @@ import ( "github.com/TeaOSLab/EdgeAPI/internal/db/models" "github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/utils" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" @@ -113,7 +114,7 @@ func (this *AuthorityNodeDAO) CreateAuthorityNode(tx *dbs.Tx, name string, descr return 0, err } secret := rands.String(32) - err = models.NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, models.NodeRoleAuthority) + err = models.NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleAuthority) if err != nil { return } diff --git a/internal/db/models/db_node_initializer.go b/internal/db/models/db_node_initializer.go index a2ea5df5..aeb62562 100644 --- a/internal/db/models/db_node_initializer.go +++ b/internal/db/models/db_node_initializer.go @@ -3,6 +3,7 @@ package models import ( "fmt" "github.com/TeaOSLab/EdgeAPI/internal/errors" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/lists" "github.com/iwind/TeaGo/logs" @@ -218,7 +219,7 @@ func (this *DBNodeInitializer) loop() error { logs.Println("[DB_NODE]create first table in database node failed: " + err.Error()) // 创建节点日志 - createLogErr := SharedNodeLogDAO.CreateLog(nil, NodeRoleDatabase, nodeId, 0, "error", "ACCESS_LOG", "can not create access log table: "+err.Error(), time.Now().Unix()) + createLogErr := SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleDatabase, nodeId, 0, "error", "ACCESS_LOG", "can not create access log table: "+err.Error(), time.Now().Unix()) if createLogErr != nil { logs.Println("[NODE_LOG]" + createLogErr.Error()) } diff --git a/internal/db/models/monitor_node_dao.go b/internal/db/models/monitor_node_dao.go index 8aa0a4c5..2ef2cb26 100644 --- a/internal/db/models/monitor_node_dao.go +++ b/internal/db/models/monitor_node_dao.go @@ -3,6 +3,7 @@ package models import ( "github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/utils" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" @@ -112,7 +113,7 @@ func (this *MonitorNodeDAO) CreateMonitorNode(tx *dbs.Tx, name string, descripti return 0, err } secret := rands.String(32) - err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, NodeRoleMonitor) + err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleMonitor) if err != nil { return } diff --git a/internal/db/models/nameservers/ns_cluster_dao.go b/internal/db/models/nameservers/ns_cluster_dao.go index f1bb3859..74812282 100644 --- a/internal/db/models/nameservers/ns_cluster_dao.go +++ b/internal/db/models/nameservers/ns_cluster_dao.go @@ -63,6 +63,15 @@ func (this *NSClusterDAO) FindEnabledNSCluster(tx *dbs.Tx, id int64) (*NSCluster return result.(*NSCluster), err } +// FindEnabledNSClusterName 查找启用中的条目名称 +func (this *NSClusterDAO) FindEnabledNSClusterName(tx *dbs.Tx, id int64) (string, error) { + return this.Query(tx). + Pk(id). + State(NSClusterStateEnabled). + Result("name"). + FindStringCol("") +} + // CreateCluster 创建集群 func (this *NSClusterDAO) CreateCluster(tx *dbs.Tx, name string) (int64, error) { op := NewNSClusterOperator() diff --git a/internal/db/models/nameservers/ns_cluster_model.go b/internal/db/models/nameservers/ns_cluster_model.go index e5384796..bc7ea4cf 100644 --- a/internal/db/models/nameservers/ns_cluster_model.go +++ b/internal/db/models/nameservers/ns_cluster_model.go @@ -2,17 +2,19 @@ package nameservers // NSCluster 域名服务器集群 type NSCluster struct { - Id uint32 `field:"id"` // ID - IsOn uint8 `field:"isOn"` // 是否启用 - Name string `field:"name"` // 集群名 - State uint8 `field:"state"` // 状态 + Id uint32 `field:"id"` // ID + IsOn uint8 `field:"isOn"` // 是否启用 + Name string `field:"name"` // 集群名 + InstallDir string `field:"installDir"` // 安装目录 + State uint8 `field:"state"` // 状态 } type NSClusterOperator struct { - Id interface{} // ID - IsOn interface{} // 是否启用 - Name interface{} // 集群名 - State interface{} // 状态 + Id interface{} // ID + IsOn interface{} // 是否启用 + Name interface{} // 集群名 + InstallDir interface{} // 安装目录 + State interface{} // 状态 } func NewNSClusterOperator() *NSClusterOperator { diff --git a/internal/db/models/nameservers/ns_node_dao.go b/internal/db/models/nameservers/ns_node_dao.go index 48cece6e..36661b0f 100644 --- a/internal/db/models/nameservers/ns_node_dao.go +++ b/internal/db/models/nameservers/ns_node_dao.go @@ -1,9 +1,17 @@ package nameservers import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeAPI/internal/errors" + "github.com/TeaOSLab/EdgeAPI/internal/utils" + "github.com/TeaOSLab/EdgeCommon/pkg/configutils" + "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" ) const ( @@ -33,7 +41,7 @@ func init() { } // EnableNSNode 启用条目 -func (this *NSNodeDAO) EnableNSNode(tx *dbs.Tx, id uint32) error { +func (this *NSNodeDAO) EnableNSNode(tx *dbs.Tx, id int64) error { _, err := this.Query(tx). Pk(id). Set("state", NSNodeStateEnabled). @@ -42,16 +50,20 @@ func (this *NSNodeDAO) EnableNSNode(tx *dbs.Tx, id uint32) error { } // DisableNSNode 禁用条目 -func (this *NSNodeDAO) DisableNSNode(tx *dbs.Tx, id uint32) error { +func (this *NSNodeDAO) DisableNSNode(tx *dbs.Tx, id int64) error { _, err := this.Query(tx). Pk(id). Set("state", NSNodeStateDisabled). Update() - return err + + if err != nil { + return err + } + return this.NotifyUpdate(tx, id) } // FindEnabledNSNode 查找启用中的条目 -func (this *NSNodeDAO) FindEnabledNSNode(tx *dbs.Tx, id uint32) (*NSNode, error) { +func (this *NSNodeDAO) FindEnabledNSNode(tx *dbs.Tx, id int64) (*NSNode, error) { result, err := this.Query(tx). Pk(id). Attr("state", NSNodeStateEnabled). @@ -61,3 +73,259 @@ func (this *NSNodeDAO) FindEnabledNSNode(tx *dbs.Tx, id uint32) (*NSNode, error) } return result.(*NSNode), err } + +// FindAllEnabledNodesWithClusterId 查找一个集群下的所有节点 +func (this *NSNodeDAO) FindAllEnabledNodesWithClusterId(tx *dbs.Tx, clusterId int64) (result []*NSNode, err error) { + _, err = this.Query(tx). + Attr("clusterId", clusterId). + State(NSNodeStateEnabled). + DescPk(). + Slice(&result). + FindAll() + return +} + +// CountAllEnabledNodes 所有集群的可用的节点数量 +func (this *NSNodeDAO) CountAllEnabledNodes(tx *dbs.Tx) (int64, error) { + return this.Query(tx). + State(NSNodeStateEnabled). + Where("clusterId IN (SELECT id FROM " + SharedNSClusterDAO.Table + " WHERE state=1)"). + Count() +} + +// CountAllEnabledNodesMatch 计算满足条件的节点数量 +func (this *NSNodeDAO) CountAllEnabledNodesMatch(tx *dbs.Tx, clusterId int64, installState configutils.BoolState, activeState configutils.BoolState, keyword string) (int64, error) { + query := this.Query(tx) + if clusterId > 0 { + query.Attr("clusterId", clusterId) + } + // 安装状态 + switch installState { + case configutils.BoolStateAll: + // 所有 + case configutils.BoolStateYes: + query.Attr("isInstalled", 1) + case configutils.BoolStateNo: + query.Attr("isInstalled", 0) + } + + // 在线状态 + switch activeState { + case configutils.BoolStateAll: + // 所有 + case configutils.BoolStateYes: + query.Where("JSON_EXTRACT(status, '$.isActive') AND UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')<=60") + case configutils.BoolStateNo: + query.Where("(status IS NULL OR NOT JSON_EXTRACT(status, '$.isActive') OR UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')>60)") + } + if len(keyword) > 0 { + query.Where("(name LIKE :keyword)"). + Param("keyword", "%"+keyword+"%") + } + + return query. + State(NSNodeStateEnabled). + Count() +} + +// ListAllEnabledNodesMatch 列出单页匹配的节点 +func (this *NSNodeDAO) ListAllEnabledNodesMatch(tx *dbs.Tx, clusterId int64, installState configutils.BoolState, activeState configutils.BoolState, keyword string, offset int64, size int64) (result []*NSNode, err error) { + query := this.Query(tx) + + // 安装状态 + switch installState { + case configutils.BoolStateAll: + // 所有 + case configutils.BoolStateYes: + query.Attr("isInstalled", 1) + case configutils.BoolStateNo: + query.Attr("isInstalled", 0) + } + + // 在线状态 + switch activeState { + case configutils.BoolStateAll: + // 所有 + case configutils.BoolStateYes: + query.Where("JSON_EXTRACT(status, '$.isActive') AND UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')<=60") + case configutils.BoolStateNo: + query.Where("(status IS NULL OR NOT JSON_EXTRACT(status, '$.isActive') OR UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')>60)") + } + + if clusterId > 0 { + query.Attr("clusterId", clusterId) + } + if len(keyword) > 0 { + query.Where("(name LIKE :keyword)"). + Param("keyword", "%"+keyword+"%") + } + _, err = query. + State(NSNodeStateEnabled). + Offset(offset). + Limit(size). + Slice(&result). + DescPk(). + FindAll() + return +} + +// CountAllLowerVersionNodesWithClusterId 计算单个集群中所有低于某个版本的节点数量 +func (this *NSNodeDAO) CountAllLowerVersionNodesWithClusterId(tx *dbs.Tx, clusterId int64, os string, arch string, version string) (int64, error) { + return this.Query(tx). + State(NSNodeStateEnabled). + Attr("clusterId", clusterId). + Where("status IS NOT NULL"). + Where("JSON_EXTRACT(status, '$.os')=:os"). + Where("JSON_EXTRACT(status, '$.arch')=:arch"). + Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)"). + Param("os", os). + Param("arch", arch). + Param("version", utils.VersionToLong(version)). + Count() +} + +// CreateNode 创建节点 +func (this *NSNodeDAO) CreateNode(tx *dbs.Tx, adminId int64, name string, clusterId int64) (nodeId int64, err error) { + uniqueId, err := this.GenUniqueId(tx) + if err != nil { + return 0, err + } + + secret := rands.String(32) + + // 保存API Token + err = models.SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleDNS) + if err != nil { + return + } + + op := NewNSNodeOperator() + op.AdminId = adminId + op.Name = name + op.UniqueId = uniqueId + op.Secret = secret + op.ClusterId = clusterId + op.IsOn = 1 + op.State = NSNodeStateEnabled + err = this.Save(tx, op) + if err != nil { + return 0, err + } + + // 通知节点更新 + nodeId = types.Int64(op.Id) + err = this.NotifyUpdate(tx, nodeId) + if err != nil { + return 0, err + } + + // 通知DNS更新 + err = this.NotifyDNSUpdate(tx, nodeId) + if err != nil { + return 0, err + } + + return nodeId, nil +} + +// UpdateNode 修改节点 +func (this *NSNodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, name string, clusterId int64, isOn bool) error { + if nodeId <= 0 { + return errors.New("invalid nodeId") + } + op := NewNSNodeOperator() + op.Id = nodeId + op.Name = name + op.ClusterId = clusterId + op.IsOn = isOn + err := this.Save(tx, op) + if err != nil { + return err + } + + err = this.NotifyUpdate(tx, nodeId) + if err != nil { + return err + } + + return this.NotifyDNSUpdate(tx, nodeId) +} + +// FindEnabledNodeIdWithUniqueId 根据唯一ID获取节点ID +func (this *NSNodeDAO) FindEnabledNodeIdWithUniqueId(tx *dbs.Tx, uniqueId string) (int64, error) { + return this.Query(tx). + Attr("uniqueId", uniqueId). + Attr("state", NSNodeStateEnabled). + ResultPk(). + FindInt64Col(0) +} + +// FindNodeInstallStatus 查询节点的安装状态 +func (this *NSNodeDAO) FindNodeInstallStatus(tx *dbs.Tx, nodeId int64) (*models.NodeInstallStatus, error) { + node, err := this.Query(tx). + Pk(nodeId). + Result("installStatus", "isInstalled"). + Find() + if err != nil { + return nil, err + } + if node == nil { + return nil, errors.New("not found") + } + + installStatus := node.(*NSNode).InstallStatus + isInstalled := node.(*NSNode).IsInstalled == 1 + if len(installStatus) == 0 { + return models.NewNodeInstallStatus(), nil + } + + status := &models.NodeInstallStatus{} + err = json.Unmarshal([]byte(installStatus), status) + if err != nil { + return nil, err + } + if isInstalled { + status.IsFinished = true + status.IsOk = true + } + return status, nil +} + +// GenUniqueId 生成唯一ID +func (this *NSNodeDAO) GenUniqueId(tx *dbs.Tx) (string, error) { + for { + uniqueId := rands.HexString(32) + ok, err := this.Query(tx). + Attr("uniqueId", uniqueId). + Exist() + if err != nil { + return "", err + } + if ok { + continue + } + return uniqueId, nil + } +} + +// UpdateNodeIsInstalled 设置节点安装状态 +func (this *NSNodeDAO) UpdateNodeIsInstalled(tx *dbs.Tx, nodeId int64, isInstalled bool) error { + _, err := this.Query(tx). + Pk(nodeId). + Set("isInstalled", isInstalled). + Set("installStatus", "null"). // 重置安装状态 + Update() + return err +} + +// NotifyUpdate 通知更新 +func (this *NSNodeDAO) NotifyUpdate(tx *dbs.Tx, nodeId int64) error { + // TODO 先什么都不做 + return nil +} + +// NotifyDNSUpdate 通知DNS更新 +func (this *NSNodeDAO) NotifyDNSUpdate(tx *dbs.Tx, nodeId int64) error { + // TODO 先什么都不做 + return nil +} diff --git a/internal/db/models/nameservers/ns_node_model.go b/internal/db/models/nameservers/ns_node_model.go index 6861b2f1..b0e2559a 100644 --- a/internal/db/models/nameservers/ns_node_model.go +++ b/internal/db/models/nameservers/ns_node_model.go @@ -2,25 +2,35 @@ package nameservers // NSNode 域名服务器节点 type NSNode struct { - Id uint32 `field:"id"` // ID - ClusterId uint32 `field:"clusterId"` // 集群ID - Name string `field:"name"` // 节点名称 - IsOn uint8 `field:"isOn"` // 是否启用 - Status string `field:"status"` // 运行状态 - UniqueId string `field:"uniqueId"` // 节点ID - Secret string `field:"secret"` // 密钥 - State uint8 `field:"state"` // 状态 + Id uint32 `field:"id"` // ID + AdminId uint32 `field:"adminId"` // 管理员ID + ClusterId uint32 `field:"clusterId"` // 集群ID + Name string `field:"name"` // 节点名称 + IsOn uint8 `field:"isOn"` // 是否启用 + Status string `field:"status"` // 运行状态 + UniqueId string `field:"uniqueId"` // 节点ID + Secret string `field:"secret"` // 密钥 + IsUp uint8 `field:"isUp"` // 是否运行 + IsInstalled uint8 `field:"isInstalled"` // 是否已安装 + InstallStatus string `field:"installStatus"` // 安装状态 + InstallDir string `field:"installDir"` // 安装目录 + State uint8 `field:"state"` // 状态 } type NSNodeOperator struct { - Id interface{} // ID - ClusterId interface{} // 集群ID - Name interface{} // 节点名称 - IsOn interface{} // 是否启用 - Status interface{} // 运行状态 - UniqueId interface{} // 节点ID - Secret interface{} // 密钥 - State interface{} // 状态 + Id interface{} // ID + AdminId interface{} // 管理员ID + ClusterId interface{} // 集群ID + Name interface{} // 节点名称 + IsOn interface{} // 是否启用 + Status interface{} // 运行状态 + UniqueId interface{} // 节点ID + Secret interface{} // 密钥 + IsUp interface{} // 是否运行 + IsInstalled interface{} // 是否已安装 + InstallStatus interface{} // 安装状态 + InstallDir interface{} // 安装目录 + State interface{} // 状态 } func NewNSNodeOperator() *NSNodeOperator { diff --git a/internal/db/models/nameservers/ns_node_model_ext.go b/internal/db/models/nameservers/ns_node_model_ext.go index e0f8e7e2..49d1f0e1 100644 --- a/internal/db/models/nameservers/ns_node_model_ext.go +++ b/internal/db/models/nameservers/ns_node_model_ext.go @@ -1 +1,42 @@ package nameservers + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" + "time" +) + +// DecodeInstallStatus 安装状态 +func (this *NSNode) DecodeInstallStatus() (*models.NodeInstallStatus, error) { + if len(this.InstallStatus) == 0 || this.InstallStatus == "null" { + return models.NewNodeInstallStatus(), nil + } + status := &models.NodeInstallStatus{} + err := json.Unmarshal([]byte(this.InstallStatus), status) + if err != nil { + return models.NewNodeInstallStatus(), err + } + + // 如果N秒钟没有更新状态,则认为不在运行 + if status.IsRunning && status.UpdatedAt < time.Now().Unix()-10 { + status.IsRunning = false + status.IsFinished = true + status.Error = "timeout" + } + + return status, nil +} + +// DecodeStatus 节点状态 +func (this *NSNode) DecodeStatus() (*nodeconfigs.NodeStatus, error) { + if len(this.Status) == 0 || this.Status == "null" { + return nil, nil + } + status := &nodeconfigs.NodeStatus{} + err := json.Unmarshal([]byte(this.Status), status) + if err != nil { + return nil, err + } + return status, nil +} diff --git a/internal/db/models/node_cluster_dao.go b/internal/db/models/node_cluster_dao.go index 3e510963..09b3779c 100644 --- a/internal/db/models/node_cluster_dao.go +++ b/internal/db/models/node_cluster_dao.go @@ -126,7 +126,7 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string } secret := rands.String(32) - err = SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, NodeRoleCluster) + err = SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleCluster) if err != nil { return 0, err } @@ -549,7 +549,7 @@ func (this *NodeClusterDAO) CheckClusterDNS(tx *dbs.Tx, cluster *NodeCluster) (i } // 检查IP地址 - ipAddr, err := SharedNodeIPAddressDAO.FindFirstNodeAccessIPAddress(tx, nodeId) + ipAddr, err := SharedNodeIPAddressDAO.FindFirstNodeAccessIPAddress(tx, nodeId, nodeconfigs.NodeRoleNode) if err != nil { return nil, err } diff --git a/internal/db/models/node_dao.go b/internal/db/models/node_dao.go index 34c1b02b..694d8a45 100644 --- a/internal/db/models/node_dao.go +++ b/internal/db/models/node_dao.go @@ -125,7 +125,7 @@ func (this *NodeDAO) CreateNode(tx *dbs.Tx, adminId int64, name string, clusterI secret := rands.String(32) // 保存API Token - err = SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, NodeRoleNode) + err = SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleNode) if err != nil { return } diff --git a/internal/db/models/node_ip_address_dao.go b/internal/db/models/node_ip_address_dao.go index e3d8645a..d86d91d1 100644 --- a/internal/db/models/node_ip_address_dao.go +++ b/internal/db/models/node_ip_address_dao.go @@ -2,6 +2,7 @@ package models import ( "errors" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" @@ -34,7 +35,7 @@ func init() { }) } -// 启用条目 +// EnableAddress 启用条目 func (this *NodeIPAddressDAO) EnableAddress(tx *dbs.Tx, id int64) (err error) { _, err = this.Query(tx). Pk(id). @@ -43,7 +44,7 @@ func (this *NodeIPAddressDAO) EnableAddress(tx *dbs.Tx, id int64) (err error) { return err } -// 禁用IP地址 +// DisableAddress 禁用IP地址 func (this *NodeIPAddressDAO) DisableAddress(tx *dbs.Tx, id int64) (err error) { _, err = this.Query(tx). Pk(id). @@ -52,11 +53,14 @@ func (this *NodeIPAddressDAO) DisableAddress(tx *dbs.Tx, id int64) (err error) { return err } -// 禁用节点的所有的IP地址 -func (this *NodeIPAddressDAO) DisableAllAddressesWithNodeId(tx *dbs.Tx, nodeId int64) error { +// DisableAllAddressesWithNodeId 禁用节点的所有的IP地址 +func (this *NodeIPAddressDAO) DisableAllAddressesWithNodeId(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole) error { if nodeId <= 0 { return errors.New("invalid nodeId") } + if len(role) == 0 { + role = nodeconfigs.NodeRoleNode + } _, err := this.Query(tx). Attr("nodeId", nodeId). Set("state", NodeIPAddressStateDisabled). @@ -64,7 +68,7 @@ func (this *NodeIPAddressDAO) DisableAllAddressesWithNodeId(tx *dbs.Tx, nodeId i return err } -// 查找启用中的IP地址 +// FindEnabledAddress 查找启用中的IP地址 func (this *NodeIPAddressDAO) FindEnabledAddress(tx *dbs.Tx, id int64) (*NodeIPAddress, error) { result, err := this.Query(tx). Pk(id). @@ -76,7 +80,7 @@ func (this *NodeIPAddressDAO) FindEnabledAddress(tx *dbs.Tx, id int64) (*NodeIPA return result.(*NodeIPAddress), err } -// 根据主键查找名称 +// FindAddressName 根据主键查找名称 func (this *NodeIPAddressDAO) FindAddressName(tx *dbs.Tx, id int64) (string, error) { return this.Query(tx). Pk(id). @@ -84,10 +88,15 @@ func (this *NodeIPAddressDAO) FindAddressName(tx *dbs.Tx, id int64) (string, err FindStringCol("") } -// 创建IP地址 -func (this *NodeIPAddressDAO) CreateAddress(tx *dbs.Tx, nodeId int64, name string, ip string, canAccess bool) (addressId int64, err error) { +// CreateAddress 创建IP地址 +func (this *NodeIPAddressDAO) CreateAddress(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole, name string, ip string, canAccess bool) (addressId int64, err error) { + if len(role) == 0 { + role = nodeconfigs.NodeRoleNode + } + op := NewNodeIPAddressOperator() op.NodeId = nodeId + op.Role = role op.Name = name op.Ip = ip op.CanAccess = canAccess @@ -105,7 +114,7 @@ func (this *NodeIPAddressDAO) CreateAddress(tx *dbs.Tx, nodeId int64, name strin return types.Int64(op.Id), nil } -// 修改IP地址 +// UpdateAddress 修改IP地址 func (this *NodeIPAddressDAO) UpdateAddress(tx *dbs.Tx, addressId int64, name string, ip string, canAccess bool) (err error) { if addressId <= 0 { return errors.New("invalid addressId") @@ -121,7 +130,7 @@ func (this *NodeIPAddressDAO) UpdateAddress(tx *dbs.Tx, addressId int64, name st return err } -// 修改IP地址中的IP +// UpdateAddressIP 修改IP地址中的IP func (this *NodeIPAddressDAO) UpdateAddressIP(tx *dbs.Tx, addressId int64, ip string) error { if addressId <= 0 { return errors.New("invalid addressId") @@ -133,7 +142,7 @@ func (this *NodeIPAddressDAO) UpdateAddressIP(tx *dbs.Tx, addressId int64, ip st return err } -// 修改IP地址所属节点 +// UpdateAddressNodeId 修改IP地址所属节点 func (this *NodeIPAddressDAO) UpdateAddressNodeId(tx *dbs.Tx, addressId int64, nodeId int64) error { _, err := this.Query(tx). Pk(addressId). @@ -151,10 +160,14 @@ func (this *NodeIPAddressDAO) UpdateAddressNodeId(tx *dbs.Tx, addressId int64, n return nil } -// 查找节点的所有的IP地址 -func (this *NodeIPAddressDAO) FindAllEnabledAddressesWithNode(tx *dbs.Tx, nodeId int64) (result []*NodeIPAddress, err error) { +// FindAllEnabledAddressesWithNode 查找节点的所有的IP地址 +func (this *NodeIPAddressDAO) FindAllEnabledAddressesWithNode(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole) (result []*NodeIPAddress, err error) { + if len(role) == 0 { + role = nodeconfigs.NodeRoleNode + } _, err = this.Query(tx). Attr("nodeId", nodeId). + Attr("role", role). State(NodeIPAddressStateEnabled). Desc("order"). AscPk(). @@ -163,10 +176,14 @@ func (this *NodeIPAddressDAO) FindAllEnabledAddressesWithNode(tx *dbs.Tx, nodeId return } -// 查找节点的第一个可访问的IP地址 -func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddress(tx *dbs.Tx, nodeId int64) (string, error) { +// FindFirstNodeAccessIPAddress 查找节点的第一个可访问的IP地址 +func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddress(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole) (string, error) { + if len(role) == 0 { + role = nodeconfigs.NodeRoleNode + } return this.Query(tx). Attr("nodeId", nodeId). + Attr("role", role). State(NodeIPAddressStateEnabled). Attr("canAccess", true). Desc("order"). @@ -175,10 +192,14 @@ func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddress(tx *dbs.Tx, nodeId in FindStringCol("") } -// 查找节点的第一个可访问的IP地址ID -func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddressId(tx *dbs.Tx, nodeId int64) (int64, error) { +// FindFirstNodeAccessIPAddressId 查找节点的第一个可访问的IP地址ID +func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddressId(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole) (int64, error) { + if len(role) == 0 { + role = nodeconfigs.NodeRoleNode + } return this.Query(tx). Attr("nodeId", nodeId). + Attr("role", role). State(NodeIPAddressStateEnabled). Attr("canAccess", true). Desc("order"). @@ -187,8 +208,11 @@ func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddressId(tx *dbs.Tx, nodeId FindInt64Col(0) } -// 查找节点所有的可访问的IP地址 -func (this *NodeIPAddressDAO) FindNodeAccessIPAddresses(tx *dbs.Tx, nodeId int64) (result []*NodeIPAddress, err error) { +// FindNodeAccessIPAddresses 查找节点所有的可访问的IP地址 +func (this *NodeIPAddressDAO) FindNodeAccessIPAddresses(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole) (result []*NodeIPAddress, err error) { + if len(role) == 0 { + role = nodeconfigs.NodeRoleNode + } _, err = this.Query(tx). Attr("nodeId", nodeId). State(NodeIPAddressStateEnabled). diff --git a/internal/db/models/node_ip_address_model.go b/internal/db/models/node_ip_address_model.go index bdc8362a..c3c24f85 100644 --- a/internal/db/models/node_ip_address_model.go +++ b/internal/db/models/node_ip_address_model.go @@ -1,9 +1,10 @@ package models -// 节点IP地址 +// NodeIPAddress 节点IP地址 type NodeIPAddress struct { Id uint32 `field:"id"` // ID NodeId uint32 `field:"nodeId"` // 节点ID + Role string `field:"role"` // 节点角色 Name string `field:"name"` // 名称 Ip string `field:"ip"` // IP地址 Description string `field:"description"` // 描述 @@ -15,6 +16,7 @@ type NodeIPAddress struct { type NodeIPAddressOperator struct { Id interface{} // ID NodeId interface{} // 节点ID + Role interface{} // 节点角色 Name interface{} // 名称 Ip interface{} // IP地址 Description interface{} // 描述 diff --git a/internal/db/models/node_log_dao.go b/internal/db/models/node_log_dao.go index ba170bf5..07fc4b99 100644 --- a/internal/db/models/node_log_dao.go +++ b/internal/db/models/node_log_dao.go @@ -3,6 +3,7 @@ package models import ( "github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeCommon/pkg/configutils" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" @@ -35,7 +36,7 @@ func init() { } // CreateLog 创建日志 -func (this *NodeLogDAO) CreateLog(tx *dbs.Tx, nodeRole NodeRole, nodeId int64, serverId int64, level string, tag string, description string, createdAt int64) error { +func (this *NodeLogDAO) CreateLog(tx *dbs.Tx, nodeRole nodeconfigs.NodeRole, nodeId int64, serverId int64, level string, tag string, description string, createdAt int64) error { hash := stringutil.Md5(nodeRole + "@" + strconv.FormatInt(nodeId, 10) + "@" + strconv.FormatInt(serverId, 10) + "@" + level + "@" + tag + "@" + description) // 检查是否在重复最后一条,避免重复创建 @@ -93,7 +94,7 @@ func (this *NodeLogDAO) CountNodeLogs(tx *dbs.Tx, role string, nodeId int64, ser query.Attr("nodeId", nodeId) } else { switch role { - case NodeRoleNode: + case nodeconfigs.NodeRoleNode: query.Where("nodeId IN (SELECT id FROM " + SharedNodeDAO.Table + " WHERE state=1)") } } @@ -138,7 +139,7 @@ func (this *NodeLogDAO) ListNodeLogs(tx *dbs.Tx, query.Attr("nodeId", nodeId) } else { switch role { - case NodeRoleNode: + case nodeconfigs.NodeRoleNode: query.Where("nodeId IN (SELECT id FROM " + SharedNodeDAO.Table + " WHERE state=1)") } } diff --git a/internal/db/models/node_roles.go b/internal/db/models/node_roles.go deleted file mode 100644 index 50f0d37b..00000000 --- a/internal/db/models/node_roles.go +++ /dev/null @@ -1,17 +0,0 @@ -package models - -type NodeRole = string - -const ( - NodeRoleAdmin NodeRole = "admin" - NodeRoleUser NodeRole = "user" - NodeRoleProvider NodeRole = "provider" - NodeRoleAPI NodeRole = "api" - NodeRoleDatabase NodeRole = "database" - NodeRoleLog NodeRole = "log" - NodeRoleDNS NodeRole = "dns" - NodeRoleMonitor NodeRole = "monitor" - NodeRoleNode NodeRole = "node" - NodeRoleCluster NodeRole = "cluster" - NodeRoleAuthority NodeRole = "authority" -) diff --git a/internal/db/models/node_value_dao.go b/internal/db/models/node_value_dao.go index ffef4f46..9bf24353 100644 --- a/internal/db/models/node_value_dao.go +++ b/internal/db/models/node_value_dao.go @@ -33,7 +33,7 @@ func init() { } // CreateValue 创建值 -func (this *NodeValueDAO) CreateValue(tx *dbs.Tx, role NodeRole, nodeId int64, item string, valueJSON []byte, createdAt int64) error { +func (this *NodeValueDAO) CreateValue(tx *dbs.Tx, role nodeconfigs.NodeRole, nodeId int64, item string, valueJSON []byte, createdAt int64) error { day := timeutil.FormatTime("Ymd", createdAt) hour := timeutil.FormatTime("YmdH", createdAt) minute := timeutil.FormatTime("YmdHi", createdAt) diff --git a/internal/db/models/user_node_dao.go b/internal/db/models/user_node_dao.go index b6c515e4..ce2bb087 100644 --- a/internal/db/models/user_node_dao.go +++ b/internal/db/models/user_node_dao.go @@ -4,6 +4,7 @@ import ( "encoding/json" "github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/utils" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" @@ -142,7 +143,7 @@ func (this *UserNodeDAO) CreateUserNode(tx *dbs.Tx, name string, description str return 0, err } secret := rands.String(32) - err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, NodeRoleUser) + err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleUser) if err != nil { return } diff --git a/internal/nodes/api_node_services.go b/internal/nodes/api_node_services.go index 663559a3..760e741b 100644 --- a/internal/nodes/api_node_services.go +++ b/internal/nodes/api_node_services.go @@ -90,4 +90,5 @@ func (this *APINode) registerServices(server *grpc.Server) { pb.RegisterNodeThresholdServiceServer(server, &services.NodeThresholdService{}) pb.RegisterHTTPFastcgiServiceServer(server, &services.HTTPFastcgiService{}) pb.RegisterNSClusterServiceServer(server, &services.NSClusterService{}) + pb.RegisterNSNodeServiceServer(server, &services.NSNodeService{}) } diff --git a/internal/remotelogs/utils.go b/internal/remotelogs/utils.go index efcbb0e4..cec389aa 100644 --- a/internal/remotelogs/utils.go +++ b/internal/remotelogs/utils.go @@ -4,6 +4,7 @@ import ( "github.com/TeaOSLab/EdgeAPI/internal/configs" teaconst "github.com/TeaOSLab/EdgeAPI/internal/const" "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/logs" "time" @@ -99,7 +100,7 @@ Loop: for { select { case log := <-logChan: - err := models.SharedNodeLogDAO.CreateLog(nil, models.NodeRoleAPI, log.NodeId, 0, log.Level, log.Tag, log.Description, log.CreatedAt) + err := models.SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleAPI, log.NodeId, 0, log.Level, log.Tag, log.Description, log.CreatedAt) if err != nil { return err } diff --git a/internal/rpc/services/service_base.go b/internal/rpc/services/service_base.go index 4fdb56b3..4d807787 100644 --- a/internal/rpc/services/service_base.go +++ b/internal/rpc/services/service_base.go @@ -7,6 +7,7 @@ import ( teaconst "github.com/TeaOSLab/EdgeAPI/internal/const" "github.com/TeaOSLab/EdgeAPI/internal/db/models" "github.com/TeaOSLab/EdgeAPI/internal/db/models/authority" + "github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers" "github.com/TeaOSLab/EdgeAPI/internal/encrypt" "github.com/TeaOSLab/EdgeAPI/internal/errors" rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils" @@ -185,6 +186,8 @@ func (this *BaseService) ValidateNodeId(ctx context.Context, roles ...rpcutils.U nodeIntId = 0 case rpcutils.UserTypeMonitor: nodeIntId, err = models.SharedMonitorNodeDAO.FindEnabledMonitorNodeIdWithUniqueId(nil, nodeId) + case rpcutils.UserTypeDNS: + nodeIntId, err = nameservers.SharedNSNodeDAO.FindEnabledNodeIdWithUniqueId(nil, nodeId) case rpcutils.UserTypeAuthority: nodeIntId, err = authority.SharedAuthorityNodeDAO.FindEnabledAuthorityNodeIdWithUniqueId(nil, nodeId) default: diff --git a/internal/rpc/services/service_dns_domain.go b/internal/rpc/services/service_dns_domain.go index cf9e8491..070dce8b 100644 --- a/internal/rpc/services/service_dns_domain.go +++ b/internal/rpc/services/service_dns_domain.go @@ -9,6 +9,7 @@ import ( "github.com/TeaOSLab/EdgeAPI/internal/errors" rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils" "github.com/TeaOSLab/EdgeAPI/internal/utils/numberutils" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/lists" "github.com/iwind/TeaGo/maps" @@ -411,7 +412,7 @@ func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster, // 新增的节点域名 nodeKeys := []string{} for _, node := range nodes { - ipAddresses, err := models.SharedNodeIPAddressDAO.FindNodeAccessIPAddresses(tx, int64(node.Id)) + ipAddresses, err := models.SharedNodeIPAddressDAO.FindNodeAccessIPAddresses(tx, int64(node.Id), nodeconfigs.NodeRoleNode) if err != nil { return nil, nil, nil, 0, 0, false, false, err } diff --git a/internal/rpc/services/service_node.go b/internal/rpc/services/service_node.go index 267424f7..71f7f461 100644 --- a/internal/rpc/services/service_node.go +++ b/internal/rpc/services/service_node.go @@ -11,6 +11,7 @@ import ( rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils" "github.com/TeaOSLab/EdgeAPI/internal/utils/numberutils" "github.com/TeaOSLab/EdgeCommon/pkg/configutils" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared" "github.com/iwind/TeaGo/logs" @@ -400,9 +401,9 @@ func (this *NodeService) UpdateNode(ctx context.Context, req *pb.UpdateNodeReque return this.Success() } -// FindEnabledNode 列出单个节点 +// FindEnabledNode 查询单个节点信息 func (this *NodeService) FindEnabledNode(ctx context.Context, req *pb.FindEnabledNodeRequest) (*pb.FindEnabledNodeResponse, error) { - _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + _, err := this.ValidateAdmin(ctx, 0) if err != nil { return nil, err } @@ -823,7 +824,7 @@ func (this *NodeService) FindAllNotInstalledNodesWithNodeClusterId(ctx context.C } // IP信息 - addresses, err := models.SharedNodeIPAddressDAO.FindAllEnabledAddressesWithNode(tx, int64(node.Id)) + addresses, err := models.SharedNodeIPAddressDAO.FindAllEnabledAddressesWithNode(tx, int64(node.Id), nodeconfigs.NodeRoleNode) if err != nil { return nil, err } @@ -932,7 +933,7 @@ func (this *NodeService) FindAllUpgradeNodesWithNodeClusterId(ctx context.Contex } // IP信息 - addresses, err := models.SharedNodeIPAddressDAO.FindAllEnabledAddressesWithNode(tx, int64(node.Id)) + addresses, err := models.SharedNodeIPAddressDAO.FindAllEnabledAddressesWithNode(tx, int64(node.Id), nodeconfigs.NodeRoleNode) if err != nil { return nil, err } @@ -1101,7 +1102,7 @@ func (this *NodeService) FindAllEnabledNodesDNSWithNodeClusterId(ctx context.Con } result := []*pb.NodeDNSInfo{} for _, node := range nodes { - ipAddresses, err := models.SharedNodeIPAddressDAO.FindNodeAccessIPAddresses(tx, int64(node.Id)) + ipAddresses, err := models.SharedNodeIPAddressDAO.FindNodeAccessIPAddresses(tx, int64(node.Id), nodeconfigs.NodeRoleNode) if err != nil { return nil, err } @@ -1162,7 +1163,7 @@ func (this *NodeService) FindEnabledNodeDNS(ctx context.Context, req *pb.FindEna return &pb.FindEnabledNodeDNSResponse{Node: nil}, nil } - ipAddr, err := models.SharedNodeIPAddressDAO.FindFirstNodeAccessIPAddress(tx, int64(node.Id)) + ipAddr, err := models.SharedNodeIPAddressDAO.FindFirstNodeAccessIPAddress(tx, int64(node.Id), nodeconfigs.NodeRoleNode) if err != nil { return nil, err } @@ -1249,7 +1250,7 @@ func (this *NodeService) UpdateNodeDNS(ctx context.Context, req *pb.UpdateNodeDN // 修改IP if len(req.IpAddr) > 0 { - ipAddrId, err := models.SharedNodeIPAddressDAO.FindFirstNodeAccessIPAddressId(tx, req.NodeId) + ipAddrId, err := models.SharedNodeIPAddressDAO.FindFirstNodeAccessIPAddressId(tx, req.NodeId, nodeconfigs.NodeRoleNode) if err != nil { return nil, err } @@ -1259,7 +1260,7 @@ func (this *NodeService) UpdateNodeDNS(ctx context.Context, req *pb.UpdateNodeDN return nil, err } } else { - _, err = models.SharedNodeIPAddressDAO.CreateAddress(tx, req.NodeId, "DNS IP", req.IpAddr, true) + _, err = models.SharedNodeIPAddressDAO.CreateAddress(tx, req.NodeId, nodeconfigs.NodeRoleNode, "DNS IP", req.IpAddr, true) if err != nil { return nil, err } diff --git a/internal/rpc/services/service_node_ip_address.go b/internal/rpc/services/service_node_ip_address.go index 038478e9..89a38b84 100644 --- a/internal/rpc/services/service_node_ip_address.go +++ b/internal/rpc/services/service_node_ip_address.go @@ -11,7 +11,7 @@ type NodeIPAddressService struct { BaseService } -// 创建IP地址 +// CreateNodeIPAddress 创建IP地址 func (this *NodeIPAddressService) CreateNodeIPAddress(ctx context.Context, req *pb.CreateNodeIPAddressRequest) (*pb.CreateNodeIPAddressResponse, error) { // 校验请求 _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) @@ -21,7 +21,7 @@ func (this *NodeIPAddressService) CreateNodeIPAddress(ctx context.Context, req * tx := this.NullTx() - addressId, err := models.SharedNodeIPAddressDAO.CreateAddress(tx, req.NodeId, req.Name, req.Ip, req.CanAccess) + addressId, err := models.SharedNodeIPAddressDAO.CreateAddress(tx, req.NodeId, req.Role, req.Name, req.Ip, req.CanAccess) if err != nil { return nil, err } @@ -29,7 +29,7 @@ func (this *NodeIPAddressService) CreateNodeIPAddress(ctx context.Context, req * return &pb.CreateNodeIPAddressResponse{AddressId: addressId}, nil } -// 修改IP地址 +// UpdateNodeIPAddress 修改IP地址 func (this *NodeIPAddressService) UpdateNodeIPAddress(ctx context.Context, req *pb.UpdateNodeIPAddressRequest) (*pb.RPCSuccess, error) { // 校验请求 _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) @@ -47,7 +47,7 @@ func (this *NodeIPAddressService) UpdateNodeIPAddress(ctx context.Context, req * return this.Success() } -// 修改IP地址所属节点 +// UpdateNodeIPAddressNodeId 修改IP地址所属节点 func (this *NodeIPAddressService) UpdateNodeIPAddressNodeId(ctx context.Context, req *pb.UpdateNodeIPAddressNodeIdRequest) (*pb.RPCSuccess, error) { // 校验请求 _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) @@ -65,7 +65,7 @@ func (this *NodeIPAddressService) UpdateNodeIPAddressNodeId(ctx context.Context, return this.Success() } -// 禁用单个IP地址 +// DisableNodeIPAddress 禁用单个IP地址 func (this *NodeIPAddressService) DisableNodeIPAddress(ctx context.Context, req *pb.DisableNodeIPAddressRequest) (*pb.DisableNodeIPAddressResponse, error) { // 校验请求 _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) @@ -83,7 +83,7 @@ func (this *NodeIPAddressService) DisableNodeIPAddress(ctx context.Context, req return &pb.DisableNodeIPAddressResponse{}, nil } -// 禁用某个节点的IP地址 +// DisableAllIPAddressesWithNodeId 禁用某个节点的IP地址 func (this *NodeIPAddressService) DisableAllIPAddressesWithNodeId(ctx context.Context, req *pb.DisableAllIPAddressesWithNodeIdRequest) (*pb.DisableAllIPAddressesWithNodeIdResponse, error) { // 校验请求 _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) @@ -93,7 +93,7 @@ func (this *NodeIPAddressService) DisableAllIPAddressesWithNodeId(ctx context.Co tx := this.NullTx() - err = models.SharedNodeIPAddressDAO.DisableAllAddressesWithNodeId(tx, req.NodeId) + err = models.SharedNodeIPAddressDAO.DisableAllAddressesWithNodeId(tx, req.NodeId, req.Role) if err != nil { return nil, err } @@ -101,10 +101,10 @@ func (this *NodeIPAddressService) DisableAllIPAddressesWithNodeId(ctx context.Co return &pb.DisableAllIPAddressesWithNodeIdResponse{}, nil } -// 查找单个IP地址 +// FindEnabledNodeIPAddress 查找单个IP地址 func (this *NodeIPAddressService) FindEnabledNodeIPAddress(ctx context.Context, req *pb.FindEnabledNodeIPAddressRequest) (*pb.FindEnabledNodeIPAddressResponse, error) { // 校验请求 - _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + _, err := this.ValidateAdmin(ctx, 0) if err != nil { return nil, err } @@ -133,7 +133,7 @@ func (this *NodeIPAddressService) FindEnabledNodeIPAddress(ctx context.Context, return &pb.FindEnabledNodeIPAddressResponse{IpAddress: result}, nil } -// 查找节点的所有地址 +// FindAllEnabledIPAddressesWithNodeId 查找节点的所有地址 func (this *NodeIPAddressService) FindAllEnabledIPAddressesWithNodeId(ctx context.Context, req *pb.FindAllEnabledIPAddressesWithNodeIdRequest) (*pb.FindAllEnabledIPAddressesWithNodeIdResponse, error) { // 校验请求 _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) @@ -143,7 +143,7 @@ func (this *NodeIPAddressService) FindAllEnabledIPAddressesWithNodeId(ctx contex tx := this.NullTx() - addresses, err := models.SharedNodeIPAddressDAO.FindAllEnabledAddressesWithNode(tx, req.NodeId) + addresses, err := models.SharedNodeIPAddressDAO.FindAllEnabledAddressesWithNode(tx, req.NodeId, req.Role) if err != nil { return nil, err } diff --git a/internal/rpc/services/service_ns_cluster.go b/internal/rpc/services/service_ns_cluster.go index 7b79d3c7..c31aebd3 100644 --- a/internal/rpc/services/service_ns_cluster.go +++ b/internal/rpc/services/service_ns_cluster.go @@ -70,9 +70,10 @@ func (this *NSClusterService) FindEnabledNSCluster(ctx context.Context, req *pb. return &pb.FindEnabledNSClusterResponse{NsCluster: nil}, nil } return &pb.FindEnabledNSClusterResponse{NsCluster: &pb.NSCluster{ - Id: int64(cluster.Id), - IsOn: cluster.IsOn == 1, - Name: cluster.Name, + Id: int64(cluster.Id), + IsOn: cluster.IsOn == 1, + Name: cluster.Name, + InstallDir: cluster.InstallDir, }}, nil } @@ -104,9 +105,10 @@ func (this *NSClusterService) ListEnabledNSClusters(ctx context.Context, req *pb var pbClusters = []*pb.NSCluster{} for _, cluster := range clusters { pbClusters = append(pbClusters, &pb.NSCluster{ - Id: int64(cluster.Id), - IsOn: cluster.IsOn == 1, - Name: cluster.Name, + Id: int64(cluster.Id), + IsOn: cluster.IsOn == 1, + Name: cluster.Name, + InstallDir: cluster.InstallDir, }) } return &pb.ListEnabledNSClustersResponse{NsClusters: pbClusters}, nil @@ -126,9 +128,10 @@ func (this *NSClusterService) FindAllEnabledNSClusters(ctx context.Context, req var pbClusters = []*pb.NSCluster{} for _, cluster := range clusters { pbClusters = append(pbClusters, &pb.NSCluster{ - Id: int64(cluster.Id), - IsOn: cluster.IsOn == 1, - Name: cluster.Name, + Id: int64(cluster.Id), + IsOn: cluster.IsOn == 1, + Name: cluster.Name, + InstallDir: cluster.InstallDir, }) } return &pb.FindAllEnabledNSClustersResponse{NsClusters: pbClusters}, nil diff --git a/internal/rpc/services/service_ns_node.go b/internal/rpc/services/service_ns_node.go new file mode 100644 index 00000000..9b07e724 --- /dev/null +++ b/internal/rpc/services/service_ns_node.go @@ -0,0 +1,315 @@ +// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. + +package services + +import ( + "context" + "github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers" + "github.com/TeaOSLab/EdgeAPI/internal/errors" + "github.com/TeaOSLab/EdgeAPI/internal/installers" + "github.com/TeaOSLab/EdgeCommon/pkg/configutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" +) + +// NSNodeService 域名服务器节点服务 +type NSNodeService struct { + BaseService +} + +// FindAllEnabledNSNodesWithNSClusterId 根据集群查找所有节点 +func (this *NSNodeService) FindAllEnabledNSNodesWithNSClusterId(ctx context.Context, req *pb.FindAllEnabledNSNodesWithNSClusterIdRequest) (*pb.FindAllEnabledNSNodesWithNSClusterIdResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + var tx = this.NullTx() + + nodes, err := nameservers.SharedNSNodeDAO.FindAllEnabledNodesWithClusterId(tx, req.NsClusterId) + if err != nil { + return nil, err + } + + pbNodes := []*pb.NSNode{} + for _, node := range nodes { + pbNodes = append(pbNodes, &pb.NSNode{ + Id: int64(node.Id), + Name: node.Name, + IsOn: node.IsOn == 1, + UniqueId: node.UniqueId, + Secret: node.Secret, + IsInstalled: node.IsInstalled == 1, + InstallDir: node.InstallDir, + IsUp: node.IsUp == 1, + NsCluster: nil, + }) + } + return &pb.FindAllEnabledNSNodesWithNSClusterIdResponse{NsNodes: pbNodes}, nil +} + +// CountAllEnabledNSNodes 所有可用的节点数量 +func (this *NSNodeService) CountAllEnabledNSNodes(ctx context.Context, req *pb.CountAllEnabledNSNodesRequest) (*pb.RPCCountResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + var tx = this.NullTx() + count, err := nameservers.SharedNSNodeDAO.CountAllEnabledNodes(tx) + if err != nil { + return nil, err + } + return this.SuccessCount(count) +} + +// CountAllEnabledNSNodesMatch 计算匹配的节点数量 +func (this *NSNodeService) CountAllEnabledNSNodesMatch(ctx context.Context, req *pb.CountAllEnabledNSNodesMatchRequest) (*pb.RPCCountResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + var tx = this.NullTx() + count, err := nameservers.SharedNSNodeDAO.CountAllEnabledNodesMatch(tx, req.NsClusterId, configutils.ToBoolState(req.InstallState), configutils.ToBoolState(req.ActiveState), req.Keyword) + if err != nil { + return nil, err + } + return this.SuccessCount(count) +} + +// ListEnabledNSNodesMatch 列出单页节点 +func (this *NSNodeService) ListEnabledNSNodesMatch(ctx context.Context, req *pb.ListEnabledNSNodesMatchRequest) (*pb.ListEnabledNSNodesMatchResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + var tx = this.NullTx() + nodes, err := nameservers.SharedNSNodeDAO.ListAllEnabledNodesMatch(tx, req.NsClusterId, configutils.ToBoolState(req.InstallState), configutils.ToBoolState(req.ActiveState), req.Keyword, req.Offset, req.Size) + pbNodes := []*pb.NSNode{} + for _, node := range nodes { + // 安装信息 + installStatus, err := node.DecodeInstallStatus() + if err != nil { + return nil, err + } + installStatusResult := &pb.NodeInstallStatus{} + if installStatus != nil { + installStatusResult = &pb.NodeInstallStatus{ + IsRunning: installStatus.IsRunning, + IsFinished: installStatus.IsFinished, + IsOk: installStatus.IsOk, + Error: installStatus.Error, + ErrorCode: installStatus.ErrorCode, + UpdatedAt: installStatus.UpdatedAt, + } + } + + pbNodes = append(pbNodes, &pb.NSNode{ + Id: int64(node.Id), + Name: node.Name, + IsOn: node.IsOn == 1, + UniqueId: node.UniqueId, + Secret: node.Secret, + IsInstalled: node.IsInstalled == 1, + InstallDir: node.InstallDir, + IsUp: node.IsUp == 1, + StatusJSON: []byte(node.Status), + InstallStatus: installStatusResult, + NsCluster: nil, + }) + } + return &pb.ListEnabledNSNodesMatchResponse{NsNodes: pbNodes}, nil +} + +// CountAllUpgradeNSNodesWithNSClusterId 计算需要升级的节点数量 +func (this *NSNodeService) CountAllUpgradeNSNodesWithNSClusterId(ctx context.Context, req *pb.CountAllUpgradeNSNodesWithNSClusterIdRequest) (*pb.RPCCountResponse, error) { + // 校验请求 + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + deployFiles := installers.SharedDeployManager.LoadFiles() + total := int64(0) + for _, deployFile := range deployFiles { + count, err := nameservers.SharedNSNodeDAO.CountAllLowerVersionNodesWithClusterId(tx, req.NsClusterId, deployFile.OS, deployFile.Arch, deployFile.Version) + if err != nil { + return nil, err + } + total += count + } + + return this.SuccessCount(total) +} + +// CreateNSNode 创建节点 +func (this *NSNodeService) CreateNSNode(ctx context.Context, req *pb.CreateNSNodeRequest) (*pb.CreateNSNodeResponse, error) { + adminId, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + nodeId, err := nameservers.SharedNSNodeDAO.CreateNode(tx, adminId, req.Name, req.NodeClusterId) + if err != nil { + return nil, err + } + + return &pb.CreateNSNodeResponse{ + NsNodeId: nodeId, + }, nil +} + +// DeleteNSNode 删除节点 +func (this *NSNodeService) DeleteNSNode(ctx context.Context, req *pb.DeleteNSNodeRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + err = nameservers.SharedNSNodeDAO.DisableNSNode(tx, req.NsNodeId) + if err != nil { + return nil, err + } + + return this.Success() +} + +// FindEnabledNSNode 查询单个节点信息 +func (this *NSNodeService) FindEnabledNSNode(ctx context.Context, req *pb.FindEnabledNSNodeRequest) (*pb.FindEnabledNSNodeResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + node, err := nameservers.SharedNSNodeDAO.FindEnabledNSNode(tx, req.NsNodeId) + if err != nil { + return nil, err + } + if node == nil { + return &pb.FindEnabledNSNodeResponse{NsNode: nil}, nil + } + + // 集群信息 + clusterName, err := nameservers.SharedNSClusterDAO.FindEnabledNSClusterName(tx, int64(node.ClusterId)) + if err != nil { + return nil, err + } + + // 安装信息 + installStatus, err := node.DecodeInstallStatus() + if err != nil { + return nil, err + } + installStatusResult := &pb.NodeInstallStatus{} + if installStatus != nil { + installStatusResult = &pb.NodeInstallStatus{ + IsRunning: installStatus.IsRunning, + IsFinished: installStatus.IsFinished, + IsOk: installStatus.IsOk, + Error: installStatus.Error, + ErrorCode: installStatus.ErrorCode, + UpdatedAt: installStatus.UpdatedAt, + } + } + + return &pb.FindEnabledNSNodeResponse{NsNode: &pb.NSNode{ + Id: int64(node.Id), + Name: node.Name, + StatusJSON: []byte(node.Status), + UniqueId: node.UniqueId, + Secret: node.Secret, + IsInstalled: node.IsInstalled == 1, + InstallDir: node.InstallDir, + NsCluster: &pb.NSCluster{ + Id: int64(node.ClusterId), + Name: clusterName, + }, + InstallStatus: installStatusResult, + IsOn: node.IsOn == 1, + }}, nil +} + +// UpdateNSNode 修改节点 +func (this *NSNodeService) UpdateNSNode(ctx context.Context, req *pb.UpdateNSNodeRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + err = nameservers.SharedNSNodeDAO.UpdateNode(tx, req.NsNodeId, req.Name, req.NsClusterId, req.IsOn) + if err != nil { + return nil, err + } + + return this.Success() +} + +// InstallNSNode 安装节点 +func (this *NSNodeService) InstallNSNode(ctx context.Context, req *pb.InstallNSNodeRequest) (*pb.InstallNSNodeResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + // TODO 需要实现 + return nil, errors.New("尚未实现此功能") + + return &pb.InstallNSNodeResponse{}, nil +} + +// FindNSNodeInstallStatus 读取节点安装状态 +func (this *NSNodeService) FindNSNodeInstallStatus(ctx context.Context, req *pb.FindNSNodeInstallStatusRequest) (*pb.FindNSNodeInstallStatusResponse, error) { + // 校验请求 + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + installStatus, err := nameservers.SharedNSNodeDAO.FindNodeInstallStatus(tx, req.NsNodeId) + if err != nil { + return nil, err + } + if installStatus == nil { + return &pb.FindNSNodeInstallStatusResponse{InstallStatus: nil}, nil + } + + pbInstallStatus := &pb.NodeInstallStatus{ + IsRunning: installStatus.IsRunning, + IsFinished: installStatus.IsFinished, + IsOk: installStatus.IsOk, + Error: installStatus.Error, + ErrorCode: installStatus.ErrorCode, + UpdatedAt: installStatus.UpdatedAt, + } + return &pb.FindNSNodeInstallStatusResponse{InstallStatus: pbInstallStatus}, nil +} + +// UpdateNSNodeIsInstalled 修改节点安装状态 +func (this *NSNodeService) UpdateNSNodeIsInstalled(ctx context.Context, req *pb.UpdateNSNodeIsInstalledRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + err = nameservers.SharedNSNodeDAO.UpdateNodeIsInstalled(tx, req.NsNodeId, req.IsInstalled) + if err != nil { + return nil, err + } + + return this.Success() +} diff --git a/internal/tasks/dns_task_executor.go b/internal/tasks/dns_task_executor.go index a181fa71..9d7f20e3 100644 --- a/internal/tasks/dns_task_executor.go +++ b/internal/tasks/dns_task_executor.go @@ -6,6 +6,7 @@ import ( dnsmodels "github.com/TeaOSLab/EdgeAPI/internal/db/models/dns" "github.com/TeaOSLab/EdgeAPI/internal/dnsclients" "github.com/TeaOSLab/EdgeAPI/internal/remotelogs" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/lists" "net" @@ -299,7 +300,7 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error { } // 所有的IP记录 - ipAddresses, err := models.SharedNodeIPAddressDAO.FindAllEnabledAddressesWithNode(tx, int64(node.Id)) + ipAddresses, err := models.SharedNodeIPAddressDAO.FindAllEnabledAddressesWithNode(tx, int64(node.Id), nodeconfigs.NodeRoleNode) if err != nil { return err } diff --git a/internal/tasks/health_check_executor.go b/internal/tasks/health_check_executor.go index 442bec1b..68b6b886 100644 --- a/internal/tasks/health_check_executor.go +++ b/internal/tasks/health_check_executor.go @@ -6,6 +6,7 @@ import ( "encoding/json" "github.com/TeaOSLab/EdgeAPI/internal/db/models" "github.com/TeaOSLab/EdgeAPI/internal/errors" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/iwind/TeaGo/lists" "github.com/iwind/TeaGo/logs" @@ -57,7 +58,7 @@ func (this *HealthCheckExecutor) Run() ([]*HealthCheckResult, error) { Node: node, } - ipAddr, err := models.NewNodeIPAddressDAO().FindFirstNodeAccessIPAddress(nil, int64(node.Id)) + ipAddr, err := models.NewNodeIPAddressDAO().FindFirstNodeAccessIPAddress(nil, int64(node.Id), nodeconfigs.NodeRoleNode) if err != nil { return nil, err }