diff --git a/build/configs/db.template.yaml b/build/configs/db.template.yaml index 7696ed29..6d8347d5 100644 --- a/build/configs/db.template.yaml +++ b/build/configs/db.template.yaml @@ -9,3 +9,7 @@ dbs: prefix: "edge" models: package: internal/web/models + + +fields: + bool: [ "uamIsOn", "followPort", "requestHostExcludingPort", "autoRemoteStart" ] diff --git a/internal/db/models/node_cluster_dao.go b/internal/db/models/node_cluster_dao.go index 811a9d8d..4f95f9c6 100644 --- a/internal/db/models/node_cluster_dao.go +++ b/internal/db/models/node_cluster_dao.go @@ -197,7 +197,7 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string } // UpdateCluster 修改集群 -func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name string, grantId int64, installDir string, timezone string, nodeMaxThreads int32, autoOpenPorts bool, clockConfig *nodeconfigs.ClockConfig) error { +func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name string, grantId int64, installDir string, timezone string, nodeMaxThreads int32, autoOpenPorts bool, clockConfig *nodeconfigs.ClockConfig, autoRemoteStart bool) error { if clusterId <= 0 { return errors.New("invalid clusterId") } @@ -222,6 +222,8 @@ func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name stri op.Clock = clockJSON } + op.AutoRemoteStart = autoRemoteStart + err := this.Save(tx, op) if err != nil { return err diff --git a/internal/db/models/node_cluster_model.go b/internal/db/models/node_cluster_model.go index 37bef0f6..e92583cc 100644 --- a/internal/db/models/node_cluster_model.go +++ b/internal/db/models/node_cluster_model.go @@ -37,6 +37,7 @@ type NodeCluster struct { Uam dbs.JSON `field:"uam"` // UAM设置 Clock dbs.JSON `field:"clock"` // 时钟配置 GlobalServerConfig dbs.JSON `field:"globalServerConfig"` // 全局服务配置 + AutoRemoteStart bool `field:"autoRemoteStart"` // 自动远程启动 } type NodeClusterOperator struct { @@ -73,6 +74,7 @@ type NodeClusterOperator struct { Uam any // UAM设置 Clock any // 时钟配置 GlobalServerConfig any // 全局服务配置 + AutoRemoteStart any // 自动远程启动 } func NewNodeClusterOperator() *NodeClusterOperator { diff --git a/internal/db/models/ns_cluster_model.go b/internal/db/models/ns_cluster_model.go index 5abe7ef6..c0be987f 100644 --- a/internal/db/models/ns_cluster_model.go +++ b/internal/db/models/ns_cluster_model.go @@ -4,35 +4,37 @@ import "github.com/iwind/TeaGo/dbs" // NSCluster 域名服务器集群 type NSCluster struct { - Id uint32 `field:"id"` // ID - IsOn bool `field:"isOn"` // 是否启用 - Name string `field:"name"` // 集群名 - InstallDir string `field:"installDir"` // 安装目录 - State uint8 `field:"state"` // 状态 - AccessLog dbs.JSON `field:"accessLog"` // 访问日志配置 - GrantId uint32 `field:"grantId"` // 授权ID - Recursion dbs.JSON `field:"recursion"` // 递归DNS设置 - Tcp dbs.JSON `field:"tcp"` // TCP设置 - Tls dbs.JSON `field:"tls"` // TLS设置 - Udp dbs.JSON `field:"udp"` // UDP设置 - DdosProtection dbs.JSON `field:"ddosProtection"` // DDoS防护设置 - Hosts dbs.JSON `field:"hosts"` // DNS主机地址 + Id uint32 `field:"id"` // ID + IsOn bool `field:"isOn"` // 是否启用 + Name string `field:"name"` // 集群名 + InstallDir string `field:"installDir"` // 安装目录 + State uint8 `field:"state"` // 状态 + AccessLog dbs.JSON `field:"accessLog"` // 访问日志配置 + GrantId uint32 `field:"grantId"` // 授权ID + Recursion dbs.JSON `field:"recursion"` // 递归DNS设置 + Tcp dbs.JSON `field:"tcp"` // TCP设置 + Tls dbs.JSON `field:"tls"` // TLS设置 + Udp dbs.JSON `field:"udp"` // UDP设置 + DdosProtection dbs.JSON `field:"ddosProtection"` // DDoS防护设置 + Hosts dbs.JSON `field:"hosts"` // DNS主机地址 + AutoRemoteStart bool `field:"autoRemoteStart"` // 自动远程启动 } type NSClusterOperator struct { - Id any // ID - IsOn any // 是否启用 - Name any // 集群名 - InstallDir any // 安装目录 - State any // 状态 - AccessLog any // 访问日志配置 - GrantId any // 授权ID - Recursion any // 递归DNS设置 - Tcp any // TCP设置 - Tls any // TLS设置 - Udp any // UDP设置 - DdosProtection any // DDoS防护设置 - Hosts any // DNS主机地址 + Id any // ID + IsOn any // 是否启用 + Name any // 集群名 + InstallDir any // 安装目录 + State any // 状态 + AccessLog any // 访问日志配置 + GrantId any // 授权ID + Recursion any // 递归DNS设置 + Tcp any // TCP设置 + Tls any // TLS设置 + Udp any // UDP设置 + DdosProtection any // DDoS防护设置 + Hosts any // DNS主机地址 + AutoRemoteStart any // 自动远程启动 } func NewNSClusterOperator() *NSClusterOperator { diff --git a/internal/rpc/services/service_node_cluster.go b/internal/rpc/services/service_node_cluster.go index 02010cb1..da0bec43 100644 --- a/internal/rpc/services/service_node_cluster.go +++ b/internal/rpc/services/service_node_cluster.go @@ -116,7 +116,7 @@ func (this *NodeClusterService) UpdateNodeCluster(ctx context.Context, req *pb.U } } - err = models.SharedNodeClusterDAO.UpdateCluster(tx, req.NodeClusterId, req.Name, req.NodeGrantId, req.InstallDir, req.TimeZone, req.NodeMaxThreads, req.AutoOpenPorts, clockConfig) + err = models.SharedNodeClusterDAO.UpdateCluster(tx, req.NodeClusterId, req.Name, req.NodeGrantId, req.InstallDir, req.TimeZone, req.NodeMaxThreads, req.AutoOpenPorts, clockConfig, req.AutoRemoteStart) if err != nil { return nil, err } @@ -167,6 +167,9 @@ func (this *NodeClusterService) FindEnabledNodeCluster(ctx context.Context, req if userId > 0 { // TODO 检查用户是否有权限 + + // 禁止通过REST访问 + // TODO } var tx = this.NullTx() @@ -197,6 +200,7 @@ func (this *NodeClusterService) FindEnabledNodeCluster(ctx context.Context, req NodeMaxThreads: int32(cluster.NodeMaxThreads), AutoOpenPorts: cluster.AutoOpenPorts == 1, ClockJSON: cluster.Clock, + AutoRemoteStart: cluster.AutoRemoteStart, }}, nil } diff --git a/internal/rpc/utils/plain_context.go b/internal/rpc/utils/plain_context.go index 716d4146..e6f5a013 100644 --- a/internal/rpc/utils/plain_context.go +++ b/internal/rpc/utils/plain_context.go @@ -5,6 +5,14 @@ import ( "time" ) +func IsRest(ctx context.Context) bool { + if ctx == nil { + return false + } + _, ok := ctx.(*PlainContext) + return ok +} + type PlainContext struct { UserType string UserId int64 diff --git a/internal/tasks/node_monitor_task.go b/internal/tasks/node_monitor_task.go index b0090816..fb9c6aa7 100644 --- a/internal/tasks/node_monitor_task.go +++ b/internal/tasks/node_monitor_task.go @@ -85,35 +85,37 @@ func (this *NodeMonitorTask) MonitorCluster(cluster *models.NodeCluster) error { } // 尝试自动远程启动 - var nodeQueue = installers.NewNodeQueue() - for _, node := range inactiveNodes { - var nodeId = int64(node.Id) - tryInfo, ok := this.recoverMap[nodeId] - if !ok { - tryInfo = &nodeStartingTry{ - count: 1, - timestamp: time.Now().Unix(), - } - this.recoverMap[nodeId] = tryInfo - } else { - if tryInfo.count >= 3 /** 3次 **/ { // N 秒内超过 M 次就暂时不再重新尝试,防止阻塞当前任务 - if tryInfo.timestamp+10*60 /** 10 分钟 **/ > time.Now().Unix() { - continue + if cluster.AutoRemoteStart { + var nodeQueue = installers.NewNodeQueue() + for _, node := range inactiveNodes { + var nodeId = int64(node.Id) + tryInfo, ok := this.recoverMap[nodeId] + if !ok { + tryInfo = &nodeStartingTry{ + count: 1, + timestamp: time.Now().Unix(), } - tryInfo.timestamp = time.Now().Unix() - tryInfo.count = 0 + this.recoverMap[nodeId] = tryInfo + } else { + if tryInfo.count >= 3 /** 3次 **/ { // N 秒内超过 M 次就暂时不再重新尝试,防止阻塞当前任务 + if tryInfo.timestamp+10*60 /** 10 分钟 **/ > time.Now().Unix() { + continue + } + tryInfo.timestamp = time.Now().Unix() + tryInfo.count = 0 + } + tryInfo.count++ } - tryInfo.count++ - } - // TODO 如果用户手工安装的位置不在标准位置,需要节点自身记住最近启动的位置 - err = nodeQueue.StartNode(nodeId) - if err != nil { - if !installers.IsGrantError(err) { - _ = models.SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleNode, nodeId, 0, 0, models.LevelError, "NODE", "start node from remote API failed: "+err.Error(), time.Now().Unix(), "", nil) + // TODO 如果用户手工安装的位置不在标准位置,需要节点自身记住最近启动的位置 + err = nodeQueue.StartNode(nodeId) + if err != nil { + if !installers.IsGrantError(err) { + _ = models.SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleNode, nodeId, 0, 0, models.LevelError, "NODE", "start node from remote API failed: "+err.Error(), time.Now().Unix(), "", nil) + } + } else { + _ = models.SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleNode, nodeId, 0, 0, models.LevelSuccess, "NODE", "start node from remote API successfully", time.Now().Unix(), "", nil) } - } else { - _ = models.SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleNode, nodeId, 0, 0, models.LevelSuccess, "NODE", "start node from remote API successfully", time.Now().Unix(), "", nil) } }