Files
waf-platform/EdgeAPI/internal/rpc/services/nameservers/service_ns_route.go
2026-02-04 20:27:13 +08:00

615 lines
16 KiB
Go

// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
//go:build plus
package nameservers
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/db/models/clients"
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/types"
"sort"
)
// NSRouteService 线路相关服务
type NSRouteService struct {
services.BaseService
}
// CreateNSRoute 创建自定义线路
func (this *NSRouteService) CreateNSRoute(ctx context.Context, req *pb.CreateNSRouteRequest) (*pb.CreateNSRouteResponse, error) {
_, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var tx = this.NullTx()
if userId > 0 {
req.UserId = userId
// 暂时不允许在集群和域名下创建线路
req.NsClusterId = 0
req.NsDomainId = 0
}
// TODO 检查线路数限制
// 检查分类是否存在
if req.NsRouteCategoryId > 0 {
if userId > 0 {
err = nameservers.SharedNSRouteCategoryDAO.CheckUserCategory(tx, userId, req.NsRouteCategoryId)
if err != nil {
return nil, err
}
} else {
exists, err := nameservers.SharedNSRouteCategoryDAO.Exist(tx, req.NsRouteCategoryId)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.New("route category id '" + types.String(req.NsRouteCategoryId) + "' not found")
}
}
} else {
req.NsRouteCategoryId = 0
}
routeId, err := nameservers.SharedNSRouteDAO.CreateRoute(tx, req.NsClusterId, req.NsDomainId, req.UserId, req.Name, req.RangesJSON, req.NsRouteCategoryId, req.Priority, req.IsPublic)
if err != nil {
return nil, err
}
return &pb.CreateNSRouteResponse{NsRouteId: routeId}, nil
}
// UpdateNSRoute 修改自定义线路
func (this *NSRouteService) UpdateNSRoute(ctx context.Context, req *pb.UpdateNSRouteRequest) (*pb.RPCSuccess, error) {
_, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var tx = this.NullTx()
// 检查权限
if userId > 0 {
err = nameservers.SharedNSRouteDAO.CheckUserRoute(tx, userId, req.NsRouteId)
if err != nil {
return nil, err
}
}
// 检查分类是否存在
if req.NsRouteCategoryId > 0 {
if userId > 0 {
err = nameservers.SharedNSRouteCategoryDAO.CheckUserCategory(tx, userId, req.NsRouteCategoryId)
if err != nil {
return nil, err
}
} else {
exists, err := nameservers.SharedNSRouteCategoryDAO.Exist(tx, req.NsRouteCategoryId)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.New("route category id '" + types.String(req.NsRouteCategoryId) + "' not found")
}
}
} else {
req.NsRouteCategoryId = 0
}
err = nameservers.SharedNSRouteDAO.UpdateRoute(tx, req.NsRouteId, req.Name, req.RangesJSON, req.NsRouteCategoryId, req.Priority, req.IsPublic, req.IsOn)
if err != nil {
return nil, err
}
return this.Success()
}
// DeleteNSRoute 删除自定义线路
func (this *NSRouteService) DeleteNSRoute(ctx context.Context, req *pb.DeleteNSRouteRequest) (*pb.RPCSuccess, error) {
_, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var tx = this.NullTx()
// 检查权限
if userId > 0 {
err = nameservers.SharedNSRouteDAO.CheckUserRoute(tx, userId, req.NsRouteId)
if err != nil {
return nil, err
}
}
err = nameservers.SharedNSRouteDAO.DisableNSRoute(tx, req.NsRouteId)
if err != nil {
return nil, err
}
return this.Success()
}
// FindNSRoute 获取单个自定义路线信息
func (this *NSRouteService) FindNSRoute(ctx context.Context, req *pb.FindNSRouteRequest) (*pb.FindNSRouteResponse, error) {
_, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var tx = this.NullTx()
// 检查权限
if userId > 0 {
err = nameservers.SharedNSRouteDAO.CheckUserRoute(tx, userId, req.NsRouteId)
if err != nil {
return nil, err
}
}
route, err := nameservers.SharedNSRouteDAO.FindEnabledNSRoute(tx, req.NsRouteId)
if err != nil {
return nil, err
}
if route == nil {
return &pb.FindNSRouteResponse{NsRoute: nil}, nil
}
// 集群
var pbCluster *pb.NSCluster
if route.ClusterId > 0 {
cluster, err := models.SharedNSClusterDAO.FindEnabledNSCluster(tx, int64(route.ClusterId))
if err != nil {
return nil, err
}
if cluster != nil {
pbCluster = &pb.NSCluster{
Id: int64(cluster.Id),
IsOn: cluster.IsOn,
Name: cluster.Name,
}
}
}
// 域名
var pbDomain *pb.NSDomain
if route.DomainId > 0 {
domain, err := nameservers.SharedNSDomainDAO.FindEnabledNSDomain(tx, int64(route.DomainId))
if err != nil {
return nil, err
}
if domain != nil {
pbDomain = &pb.NSDomain{
Id: int64(domain.Id),
Name: domain.Name,
IsOn: domain.IsOn,
}
}
}
// 分类
var pbCategory *pb.NSRouteCategory
if route.CategoryId > 0 {
category, err := nameservers.SharedNSRouteCategoryDAO.FindCategory(tx, int64(route.CategoryId))
if err != nil {
return nil, err
}
if category != nil {
pbCategory = &pb.NSRouteCategory{
Id: int64(category.Id),
Name: category.Name,
IsOn: category.IsOn,
}
}
}
return &pb.FindNSRouteResponse{NsRoute: &pb.NSRoute{
Id: int64(route.Id),
IsOn: route.IsOn,
Name: route.Name,
RangesJSON: route.Ranges,
IsPublic: route.IsPublic,
Priority: types.Int32(route.Priority),
NsCluster: pbCluster,
NsDomain: pbDomain,
NsRouteCategory: pbCategory,
}}, nil
}
// CountAllNSRoutes 查询自定义线路数量
func (this *NSRouteService) CountAllNSRoutes(ctx context.Context, req *pb.CountAllNSRoutesRequest) (*pb.RPCCountResponse, error) {
_, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
if userId > 0 {
req.UserId = userId
}
var tx = this.NullTx()
countRoutes, err := nameservers.SharedNSRouteDAO.CountAllEnabledRoutes(tx, req.NsClusterId, req.NsClusterId, req.UserId)
if err != nil {
return nil, err
}
return this.SuccessCount(countRoutes)
}
// FindAllNSRoutes 读取所有自定义线路
func (this *NSRouteService) FindAllNSRoutes(ctx context.Context, req *pb.FindAllNSRoutesRequest) (*pb.FindAllNSRoutesResponse, error) {
_, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var tx = this.NullTx()
if userId > 0 {
req.UserId = userId
}
routes, err := nameservers.SharedNSRouteDAO.FindAllEnabledRoutes(tx, req.NsClusterId, req.NsDomainId, req.UserId, req.NsRouteCategoryId)
if err != nil {
return nil, err
}
var pbRoutes = []*pb.NSRoute{}
for _, route := range routes {
// 集群
var pbCluster *pb.NSCluster
if route.ClusterId > 0 {
cluster, err := models.SharedNSClusterDAO.FindEnabledNSCluster(tx, int64(route.ClusterId))
if err != nil {
return nil, err
}
if cluster != nil {
pbCluster = &pb.NSCluster{
Id: int64(cluster.Id),
IsOn: cluster.IsOn,
Name: cluster.Name,
}
}
}
// 域名
var pbDomain *pb.NSDomain
if route.DomainId > 0 {
domain, err := nameservers.SharedNSDomainDAO.FindEnabledNSDomain(tx, int64(route.DomainId))
if err != nil {
return nil, err
}
if domain != nil {
pbDomain = &pb.NSDomain{
Id: int64(domain.Id),
Name: domain.Name,
IsOn: domain.IsOn,
}
}
}
// 分类
var pbCategory *pb.NSRouteCategory
if route.CategoryId > 0 {
category, err := nameservers.SharedNSRouteCategoryDAO.FindCategory(tx, int64(route.CategoryId))
if err != nil {
return nil, err
}
if category != nil {
pbCategory = &pb.NSRouteCategory{
Id: int64(category.Id),
Name: category.Name,
IsOn: category.IsOn,
Order: types.Int32(category.Order),
}
}
}
pbRoutes = append(pbRoutes, &pb.NSRoute{
Id: int64(route.Id),
IsOn: route.IsOn,
Code: "id:" + types.String(route.Id),
Name: route.Name,
IsPublic: route.IsPublic,
RangesJSON: route.Ranges,
Order: types.Int32(route.Order),
Priority: types.Int32(route.Priority),
NsCluster: pbCluster,
NsDomain: pbDomain,
NsRouteCategory: pbCategory,
})
}
// 按照分类排序
if len(pbRoutes) > 0 {
sort.Slice(pbRoutes, func(i, j int) bool {
var route1 = pbRoutes[i]
var route2 = pbRoutes[j]
// route1.category = nil
if route1.NsRouteCategory == nil {
if route2.NsRouteCategory == nil {
if route1.Order == route2.Order {
return route1.Id < route2.Id
}
return route1.Order > route2.Order
}
return true
}
// route1.category != nil && route2.category = nil
if route2.NsRouteCategory == nil {
return false
}
// 同一个分类
if route1.NsRouteCategory.Id == route2.NsRouteCategory.Id {
if route1.Order == route2.Order {
return route1.Id < route2.Id
}
return route1.Order > route2.Order
}
if route1.NsRouteCategory.Order == route2.NsRouteCategory.Order {
return route1.NsRouteCategory.Id < route2.NsRouteCategory.Id
}
return route1.NsRouteCategory.Order > route2.NsRouteCategory.Order
})
}
return &pb.FindAllNSRoutesResponse{NsRoutes: pbRoutes}, nil
}
// FindAllPublicNSRoutes 读取所有公用的自定义线路
// 目前只允许读取系统管理员设置的公用自定义线路
func (this *NSRouteService) FindAllPublicNSRoutes(ctx context.Context, req *pb.FindAllPublicRoutesRequest) (*pb.FindAllPublicRoutesResponse, error) {
_, err := this.ValidateUserNode(ctx, false)
if err != nil {
return nil, err
}
var tx = this.NullTx()
routes, err := nameservers.SharedNSRouteDAO.FindAllPublicRoutes(tx)
if err != nil {
return nil, err
}
var pbRoutes = []*pb.NSRoute{}
for _, route := range routes {
// 分类
var pbCategory *pb.NSRouteCategory
if route.CategoryId > 0 {
category, err := nameservers.SharedNSRouteCategoryDAO.FindCategory(tx, int64(route.CategoryId))
if err != nil {
return nil, err
}
if category != nil {
// 如果分类未启用,则当前分类下面的线路也不显示
if !category.IsOn {
continue
}
pbCategory = &pb.NSRouteCategory{
Id: int64(category.Id),
Name: category.Name,
IsOn: category.IsOn,
Order: types.Int32(category.Order),
}
}
}
pbRoutes = append(pbRoutes, &pb.NSRoute{
Id: int64(route.Id),
IsOn: route.IsOn,
Code: "id:" + types.String(route.Id),
Name: route.Name,
IsPublic: route.IsPublic,
RangesJSON: route.Ranges,
Order: types.Int32(route.Order),
Priority: types.Int32(route.Priority),
NsCluster: nil,
NsDomain: nil,
NsRouteCategory: pbCategory,
})
}
// 按照分类排序
if len(pbRoutes) > 0 {
sort.Slice(pbRoutes, func(i, j int) bool {
var route1 = pbRoutes[i]
var route2 = pbRoutes[j]
// route1.category = nil
if route1.NsRouteCategory == nil {
if route2.NsRouteCategory == nil {
if route1.Order == route2.Order {
return route1.Id < route2.Id
}
return route1.Order > route2.Order
}
return true
}
// route1.category != nil && route2.category = nil
if route2.NsRouteCategory == nil {
return false
}
// 同一个分类
if route1.NsRouteCategory.Id == route2.NsRouteCategory.Id {
if route1.Order == route2.Order {
return route1.Id < route2.Id
}
return route1.Order > route2.Order
}
if route1.NsRouteCategory.Order == route2.NsRouteCategory.Order {
return route1.NsRouteCategory.Id < route2.NsRouteCategory.Id
}
return route1.NsRouteCategory.Order > route2.NsRouteCategory.Order
})
}
return &pb.FindAllPublicRoutesResponse{NsRoutes: pbRoutes}, nil
}
// UpdateNSRouteOrders 设置自定义线路排序
func (this *NSRouteService) UpdateNSRouteOrders(ctx context.Context, req *pb.UpdateNSRouteOrdersRequest) (*pb.RPCSuccess, error) {
_, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var tx = this.NullTx()
// 检查权限
if userId > 0 {
for _, routeId := range req.NsRouteIds {
err = nameservers.SharedNSRouteDAO.CheckUserRoute(tx, userId, routeId)
if err != nil {
return nil, err
}
}
}
err = nameservers.SharedNSRouteDAO.UpdateRouteOrders(tx, req.NsRouteIds)
if err != nil {
return nil, err
}
return this.Success()
}
// ListNSRoutesAfterVersion 根据版本列出一组自定义线路
func (this *NSRouteService) ListNSRoutesAfterVersion(ctx context.Context, req *pb.ListNSRoutesAfterVersionRequest) (*pb.ListNSRoutesAfterVersionResponse, error) {
_, _, err := this.ValidateNodeId(ctx, rpcutils.UserTypeDNS)
if err != nil {
return nil, err
}
// 集群ID
var tx = this.NullTx()
routes, err := nameservers.SharedNSRouteDAO.ListRoutesAfterVersion(tx, req.Version, 2000)
if err != nil {
return nil, err
}
var pbRoutes []*pb.NSRoute
for _, route := range routes {
// 集群
var pbCluster *pb.NSCluster
if route.ClusterId > 0 {
pbCluster = &pb.NSCluster{Id: int64(route.ClusterId)}
}
// 域名
var pbDomain *pb.NSDomain
if route.DomainId > 0 {
pbDomain = &pb.NSDomain{Id: int64(route.DomainId)}
}
pbRoutes = append(pbRoutes, &pb.NSRoute{
Id: int64(route.Id),
IsOn: route.IsOn,
Name: "",
RangesJSON: route.Ranges,
IsDeleted: route.State == nameservers.NSRouteStateDisabled,
Order: types.Int32(route.Order),
Priority: types.Int32(route.Priority),
Version: int64(route.Version),
UserId: types.Int64(route.UserId),
NsCluster: pbCluster,
NsDomain: pbDomain,
})
}
return &pb.ListNSRoutesAfterVersionResponse{NsRoutes: pbRoutes}, nil
}
// FindAllDefaultWorldRegionRoutes 查找默认的世界区域线路
func (this *NSRouteService) FindAllDefaultWorldRegionRoutes(ctx context.Context, req *pb.FindAllDefaultWorldRegionRoutesRequest) (*pb.FindAllDefaultWorldRegionRoutesResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var pbRoutes = []*pb.NSRoute{}
for _, route := range dnsconfigs.AllDefaultWorldRegionRoutes {
pbRoutes = append(pbRoutes, &pb.NSRoute{
Code: route.Code,
Name: route.Name,
})
}
return &pb.FindAllDefaultWorldRegionRoutesResponse{
NsRoutes: pbRoutes,
}, nil
}
// FindAllDefaultChinaProvinceRoutes 查找默认的中国省份线路
func (this *NSRouteService) FindAllDefaultChinaProvinceRoutes(ctx context.Context, req *pb.FindAllDefaultChinaProvinceRoutesRequest) (*pb.FindAllDefaultChinaProvinceRoutesResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var pbRoutes = []*pb.NSRoute{}
for _, route := range dnsconfigs.AllDefaultChinaProvinceRoutes {
pbRoutes = append(pbRoutes, &pb.NSRoute{
Code: route.Code,
Name: route.Name,
})
}
return &pb.FindAllDefaultChinaProvinceRoutesResponse{
NsRoutes: pbRoutes,
}, nil
}
// FindAllDefaultISPRoutes 查找默认的ISP线路
func (this *NSRouteService) FindAllDefaultISPRoutes(ctx context.Context, req *pb.FindAllDefaultISPRoutesRequest) (*pb.FindAllDefaultISPRoutesResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var pbRoutes = []*pb.NSRoute{}
for _, route := range dnsconfigs.AllDefaultISPRoutes {
pbRoutes = append(pbRoutes, &pb.NSRoute{
Code: route.Code,
Name: route.Name,
})
}
return &pb.FindAllDefaultISPRoutesResponse{
NsRoutes: pbRoutes,
}, nil
}
// FindAllAgentNSRoutes 查找默认的搜索引擎线路
func (this *NSRouteService) FindAllAgentNSRoutes(ctx context.Context, req *pb.FindAllAgentNSRoutesRequest) (*pb.FindAllAgentNSRoutesResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var tx = this.NullTx()
agents, err := clients.SharedClientAgentDAO.FindAllNSAgents(tx)
if err != nil {
return nil, err
}
var pbRoutes = []*pb.NSRoute{}
for _, agent := range agents {
pbRoutes = append(pbRoutes, &pb.NSRoute{
Code: agent.NSRouteCode(),
Name: agent.Name,
})
}
pbRoutes = append(pbRoutes, &pb.NSRoute{
Code: "agent",
Name: "搜索引擎",
})
return &pb.FindAllAgentNSRoutesResponse{NsRoutes: pbRoutes}, nil
}