diff --git a/internal/db/models/node_dao.go b/internal/db/models/node_dao.go index 40d8c03f..4593a5ef 100644 --- a/internal/db/models/node_dao.go +++ b/internal/db/models/node_dao.go @@ -598,6 +598,52 @@ func (this *NodeDAO) CountAllEnabledNodesWithGroupId(groupId int64) (int64, erro Count() } +// 获取一个集群的节点DNS信息 +func (this *NodeDAO) FindAllEnabledNodesDNSWithClusterId(clusterId int64) (result []*Node, err error) { + _, err = this.Query(). + State(NodeStateEnabled). + Attr("clusterId", clusterId). + Attr("isOn", true). + Result("id", "name", "dnsRoutes"). + DescPk(). + Slice(&result). + FindAll() + return +} + +// 获取单个节点的DNS信息 +func (this *NodeDAO) FindEnabledNodeDNS(nodeId int64) (*Node, error) { + one, err := this.Query(). + State(NodeStateEnabled). + Pk(nodeId). + Attr("isOn", true). + Result("id", "name", "dnsRoutes", "clusterId"). + Find() + if err != nil || one == nil { + return nil, err + } + return one.(*Node), nil +} + +// 修改节点的DNS信息 +func (this *NodeDAO) UpdateNodeDNS(nodeId int64, routes map[int64]string) error { + if nodeId <= 0 { + return errors.New("invalid nodeId") + } + if routes == nil { + routes = map[int64]string{} + } + routesJSON, err := json.Marshal(routes) + if err != nil { + return err + } + op := NewNodeOperator() + op.Id = nodeId + op.DnsRoutes = routesJSON + _, err = this.Save(op) + return err +} + // 生成唯一ID func (this *NodeDAO) genUniqueId() (string, error) { for { diff --git a/internal/db/models/node_ip_address_dao.go b/internal/db/models/node_ip_address_dao.go index 28a74925..aac62532 100644 --- a/internal/db/models/node_ip_address_dao.go +++ b/internal/db/models/node_ip_address_dao.go @@ -115,6 +115,18 @@ func (this *NodeIPAddressDAO) UpdateAddress(addressId int64, name string, ip str return err } +// 修改IP地址中的IP +func (this *NodeIPAddressDAO) UpdateAddressIP(addressId int64, ip string) error { + if addressId <= 0 { + return errors.New("invalid addressId") + } + op := NewNodeIPAddressOperator() + op.Id = addressId + op.Ip = ip + _, err := this.Save(op) + return err +} + // 修改IP地址所属节点 func (this *NodeIPAddressDAO) UpdateAddressNodeId(addressId int64, nodeId int64) error { _, err := this.Query(). @@ -148,3 +160,15 @@ func (this *NodeIPAddressDAO) FindFirstNodeIPAddress(nodeId int64) (string, erro Result("ip"). FindStringCol("") } + +// 查找节点的第一个可访问的IP地址ID +func (this *NodeIPAddressDAO) FindFirstNodeIPAddressId(nodeId int64) (int64, error) { + return this.Query(). + Attr("nodeId", nodeId). + State(NodeIPAddressStateEnabled). + Attr("canAccess", true). + Desc("order"). + AscPk(). + Result("id"). + FindInt64Col(0) +} diff --git a/internal/db/models/node_model_ext.go b/internal/db/models/node_model_ext.go index e7b29955..8acf3766 100644 --- a/internal/db/models/node_model_ext.go +++ b/internal/db/models/node_model_ext.go @@ -40,6 +40,19 @@ func (this *Node) DecodeStatus() (*nodeconfigs.NodeStatus, error) { return status, nil } +// 所有的DNS线路 +func (this *Node) DNSRoutes() (map[int64]string, error) { + routes := map[int64]string{} // domainId => route + if len(this.DnsRoutes) == 0 || this.DnsRoutes == "null" { + return routes, nil + } + err := json.Unmarshal([]byte(this.DnsRoutes), &routes) + if err != nil { + return map[int64]string{}, err + } + return routes, nil +} + // DNS线路 func (this *Node) DNSRoute(dnsDomainId int64) (string, error) { routes := map[int64]string{} // domainId => route diff --git a/internal/rpc/services/service_node.go b/internal/rpc/services/service_node.go index e9c4c1ef..dc5baf04 100644 --- a/internal/rpc/services/service_node.go +++ b/internal/rpc/services/service_node.go @@ -7,6 +7,7 @@ import ( "github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/installers" 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/rpc/pb" "github.com/iwind/TeaGo/logs" @@ -837,3 +838,151 @@ func (this *NodeService) CountAllEnabledNodesWithGroupId(ctx context.Context, re } return &pb.RPCCountResponse{Count: count}, nil } + +// 取得某个集群下的所有节点 +func (this *NodeService) FindAllEnabledNodesDNSWithClusterId(ctx context.Context, req *pb.FindAllEnabledNodesDNSWithClusterIdRequest) (*pb.FindAllEnabledNodesDNSWithClusterIdResponse, error) { + // 校验请求 + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + clusterDNS, err := models.SharedNodeClusterDAO.FindClusterDNSInfo(req.NodeClusterId) + if err != nil { + return nil, err + } + if clusterDNS == nil { + return nil, errors.New("not found clusterId '" + numberutils.FormatInt64(req.NodeClusterId) + "'") + } + dnsDomainId := int64(clusterDNS.DnsDomainId) + + nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(req.NodeClusterId) + if err != nil { + return nil, err + } + result := []*pb.NodeDNSInfo{} + for _, node := range nodes { + ipAddr, err := models.SharedNodeIPAddressDAO.FindFirstNodeIPAddress(int64(node.Id)) + if err != nil { + return nil, err + } + + route, err := node.DNSRoute(dnsDomainId) + if err != nil { + return nil, err + } + + result = append(result, &pb.NodeDNSInfo{ + Id: int64(node.Id), + Name: node.Name, + IpAddr: ipAddr, + Route: route, + }) + } + return &pb.FindAllEnabledNodesDNSWithClusterIdResponse{Nodes: result}, nil +} + +// 查找单个节点的域名解析信息 +func (this *NodeService) FindEnabledNodeDNS(ctx context.Context, req *pb.FindEnabledNodeDNSRequest) (*pb.FindEnabledNodeDNSResponse, error) { + // 校验请求 + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + node, err := models.SharedNodeDAO.FindEnabledNodeDNS(req.NodeId) + if err != nil { + return nil, err + } + + if node == nil { + return &pb.FindEnabledNodeDNSResponse{Node: nil}, nil + } + + clusterId := int64(node.ClusterId) + clusterDNS, err := models.SharedNodeClusterDAO.FindClusterDNSInfo(clusterId) + if err != nil { + return nil, err + } + if clusterDNS == nil { + return &pb.FindEnabledNodeDNSResponse{Node: nil}, nil + } + + dnsDomainId := int64(clusterDNS.DnsDomainId) + + var route = "" + if dnsDomainId > 0 { + route, err = node.DNSRoute(dnsDomainId) + if err != nil { + return nil, err + } + } + + ipAddr, err := models.SharedNodeIPAddressDAO.FindFirstNodeIPAddress(int64(node.Id)) + if err != nil { + return nil, err + } + + return &pb.FindEnabledNodeDNSResponse{ + Node: &pb.NodeDNSInfo{ + Id: int64(node.Id), + Name: node.Name, + IpAddr: ipAddr, + Route: route, + ClusterId: clusterId, + DnsDomainId: dnsDomainId, + }, + }, nil +} + +// 修改节点的DNS解析信息 +func (this *NodeService) UpdateNodeDNS(ctx context.Context, req *pb.UpdateNodeDNSRequest) (*pb.RPCSuccess, error) { + // 校验请求 + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + node, err := models.SharedNodeDAO.FindEnabledNodeDNS(req.NodeId) + if err != nil { + return nil, err + } + + if node == nil { + return nil, errors.New("node not found") + } + + routes, err := node.DNSRoutes() + if err != nil { + return nil, err + } + if req.DnsDomainId > 0 && len(req.Route) > 0 { + routes[req.DnsDomainId] = req.Route + } + + err = models.SharedNodeDAO.UpdateNodeDNS(req.NodeId, routes) + if err != nil { + return nil, err + } + + // 修改IP + if len(req.IpAddr) > 0 { + ipAddrId, err := models.SharedNodeIPAddressDAO.FindFirstNodeIPAddressId(req.NodeId) + if err != nil { + return nil, err + } + if ipAddrId > 0 { + err = models.SharedNodeIPAddressDAO.UpdateAddressIP(ipAddrId, req.IpAddr) + if err != nil { + return nil, err + } + } else { + _, err = models.SharedNodeIPAddressDAO.CreateAddress(req.NodeId, "DNS IP", req.IpAddr, true) + if err != nil { + return nil, err + } + } + } + + return rpcutils.Success() +} diff --git a/internal/rpc/services/service_node_cluster.go b/internal/rpc/services/service_node_cluster.go index 90550b8e..79ab7236 100644 --- a/internal/rpc/services/service_node_cluster.go +++ b/internal/rpc/services/service_node_cluster.go @@ -407,6 +407,7 @@ func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, r if provider != nil { pbProvider = &pb.DNSProvider{ Id: int64(provider.Id), + Name: provider.Name, Type: provider.Type, TypeName: dnsclients.FindProviderTypeName(provider.Type), }