Files
waf-platform/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_node.go
2026-02-27 10:35:22 +08:00

186 lines
5.1 KiB
Go

package httpdns
import (
"context"
"encoding/json"
"errors"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/installers"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/logs"
)
// HTTPDNSNodeService HTTPDNS节点服务
type HTTPDNSNodeService struct {
services.BaseService
pb.UnimplementedHTTPDNSNodeServiceServer
}
func (this *HTTPDNSNodeService) CreateHTTPDNSNode(ctx context.Context, req *pb.CreateHTTPDNSNodeRequest) (*pb.CreateHTTPDNSNodeResponse, error) {
_, err := this.ValidateAdmin(ctx)
if err != nil {
return nil, err
}
if req.ClusterId <= 0 {
return nil, errors.New("required 'clusterId'")
}
var nodeId int64
err = this.RunTx(func(tx *dbs.Tx) error {
nodeId, err = models.SharedHTTPDNSNodeDAO.CreateNode(tx, req.ClusterId, req.Name, req.InstallDir, req.IsOn)
if err != nil {
return err
}
return notifyHTTPDNSClusterTask(tx, req.ClusterId, models.HTTPDNSNodeTaskTypeConfigChanged)
})
if err != nil {
return nil, err
}
return &pb.CreateHTTPDNSNodeResponse{NodeId: nodeId}, nil
}
func (this *HTTPDNSNodeService) UpdateHTTPDNSNode(ctx context.Context, req *pb.UpdateHTTPDNSNodeRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx)
if err != nil {
return nil, err
}
err = this.RunTx(func(tx *dbs.Tx) error {
node, err := models.SharedHTTPDNSNodeDAO.FindEnabledNode(tx, req.NodeId)
if err != nil {
return err
}
if node == nil {
return errors.New("node not found")
}
err = models.SharedHTTPDNSNodeDAO.UpdateNode(tx, req.NodeId, req.Name, req.InstallDir, req.IsOn)
if err != nil {
return err
}
return notifyHTTPDNSClusterTask(tx, int64(node.ClusterId), models.HTTPDNSNodeTaskTypeConfigChanged)
})
if err != nil {
return nil, err
}
return this.Success()
}
func (this *HTTPDNSNodeService) DeleteHTTPDNSNode(ctx context.Context, req *pb.DeleteHTTPDNSNodeRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx)
if err != nil {
return nil, err
}
err = this.RunTx(func(tx *dbs.Tx) error {
node, err := models.SharedHTTPDNSNodeDAO.FindEnabledNode(tx, req.NodeId)
if err != nil {
return err
}
if node == nil {
return nil
}
err = models.SharedHTTPDNSNodeDAO.DisableNode(tx, req.NodeId)
if err != nil {
return err
}
return notifyHTTPDNSClusterTask(tx, int64(node.ClusterId), models.HTTPDNSNodeTaskTypeConfigChanged)
})
if err != nil {
return nil, err
}
return this.Success()
}
func (this *HTTPDNSNodeService) FindHTTPDNSNode(ctx context.Context, req *pb.FindHTTPDNSNodeRequest) (*pb.FindHTTPDNSNodeResponse, error) {
nodeId := req.NodeId
if nodeId <= 0 {
parsedNodeId, nodeErr := this.ValidateHTTPDNSNode(ctx)
if nodeErr != nil {
return nil, errors.New("invalid 'nodeId'")
}
nodeId = parsedNodeId
} else {
_, _, validateErr := this.ValidateAdminAndUser(ctx, true)
if validateErr != nil {
if _, nodeErr := this.ValidateHTTPDNSNode(ctx); nodeErr != nil {
return nil, validateErr
}
}
}
node, err := models.SharedHTTPDNSNodeDAO.FindEnabledNode(this.NullTx(), nodeId)
if err != nil {
return nil, err
}
return &pb.FindHTTPDNSNodeResponse{Node: toPBNode(node)}, nil
}
func (this *HTTPDNSNodeService) ListHTTPDNSNodes(ctx context.Context, req *pb.ListHTTPDNSNodesRequest) (*pb.ListHTTPDNSNodesResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
nodes, err := models.SharedHTTPDNSNodeDAO.ListEnabledNodes(this.NullTx(), req.ClusterId)
if err != nil {
return nil, err
}
var pbNodes []*pb.HTTPDNSNode
for _, node := range nodes {
pbNodes = append(pbNodes, toPBNode(node))
}
return &pb.ListHTTPDNSNodesResponse{Nodes: pbNodes}, nil
}
func (this *HTTPDNSNodeService) UpdateHTTPDNSNodeStatus(ctx context.Context, req *pb.UpdateHTTPDNSNodeStatusRequest) (*pb.RPCSuccess, error) {
nodeId := req.GetNodeId()
isAdminCaller := false
if nodeId > 0 {
if _, adminErr := this.ValidateAdmin(ctx); adminErr == nil {
isAdminCaller = true
}
}
if !isAdminCaller {
if nodeId <= 0 {
parsedNodeId, err := this.ValidateHTTPDNSNode(ctx)
if err != nil {
return nil, err
}
nodeId = parsedNodeId
}
}
if nodeId <= 0 {
return nil, errors.New("invalid 'nodeId'")
}
err := models.SharedHTTPDNSNodeDAO.UpdateNodeStatus(this.NullTx(), nodeId, req.GetIsUp(), req.GetIsInstalled(), req.GetIsActive(), req.GetStatusJSON(), req.GetInstallStatusJSON())
if err != nil {
return nil, err
}
if isAdminCaller && shouldTriggerHTTPDNSInstall(req.GetInstallStatusJSON()) {
goman.New(func() {
installErr := installers.SharedHTTPDNSNodeQueue().InstallNodeProcess(nodeId, false)
if installErr != nil {
logs.Println("[RPC][HTTPDNS]install node failed:", installErr.Error())
}
})
}
return this.Success()
}
func shouldTriggerHTTPDNSInstall(installStatusJSON []byte) bool {
if len(installStatusJSON) == 0 {
return false
}
installStatus := &models.NodeInstallStatus{}
err := json.Unmarshal(installStatusJSON, installStatus)
if err != nil {
return false
}
return installStatus.IsRunning && !installStatus.IsFinished
}