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/nodeconfigs" "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 } pbNode := toPBNode(node) // 认证信息 if pbNode != nil { login, loginErr := models.SharedNodeLoginDAO.FindEnabledNodeLoginWithNodeId(this.NullTx(), nodeconfigs.NodeRoleHTTPDNS, nodeId) if loginErr != nil { return nil, loginErr } if login != nil { pbNode.NodeLogin = &pb.NodeLogin{ Id: int64(login.Id), Name: login.Name, Type: login.Type, Params: login.Params, } } } return &pb.FindHTTPDNSNodeResponse{Node: pbNode}, 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() } // UpdateHTTPDNSNodeLogin 修改HTTPDNS节点登录信息 func (this *HTTPDNSNodeService) UpdateHTTPDNSNodeLogin(ctx context.Context, req *pb.UpdateHTTPDNSNodeLoginRequest) (*pb.RPCSuccess, error) { _, err := this.ValidateAdmin(ctx) if err != nil { return nil, err } var tx = this.NullTx() if req.NodeLogin.Id <= 0 { loginId, createErr := models.SharedNodeLoginDAO.CreateNodeLogin(tx, nodeconfigs.NodeRoleHTTPDNS, req.NodeId, req.NodeLogin.Name, req.NodeLogin.Type, req.NodeLogin.Params) if createErr != nil { return nil, createErr } req.NodeLogin.Id = loginId } err = models.SharedNodeLoginDAO.UpdateNodeLogin(tx, req.NodeLogin.Id, req.NodeLogin.Name, req.NodeLogin.Type, req.NodeLogin.Params) if err != nil { return nil, err } 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 }