1.4.5.2
This commit is contained in:
263
EdgeAPI/internal/rpc/services/nameservers/service_ns.go
Normal file
263
EdgeAPI/internal/rpc/services/nameservers/service_ns.go
Normal file
@@ -0,0 +1,263 @@
|
||||
// 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/nameservers"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NSService 域名服务
|
||||
type NSService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// ComposeNSBoard 组合看板数据
|
||||
func (this *NSService) ComposeNSBoard(ctx context.Context, req *pb.ComposeNSBoardRequest) (*pb.ComposeNSBoardResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
var result = &pb.ComposeNSBoardResponse{}
|
||||
|
||||
// 域名
|
||||
countDomains, err := nameservers.SharedNSDomainDAO.CountAllEnabledDomains(tx, 0, 0, 0, dnsconfigs.NSDomainStatusVerified, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.CountNSDomains = countDomains
|
||||
|
||||
// 记录
|
||||
countRecords, err := nameservers.SharedNSRecordDAO.CountAllEnabledRecords(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.CountNSRecords = countRecords
|
||||
|
||||
// 集群数
|
||||
countClusters, err := models.SharedNSClusterDAO.CountAllEnabledClusters(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.CountNSClusters = countClusters
|
||||
|
||||
// 节点数
|
||||
countNodes, err := models.SharedNSNodeDAO.CountAllEnabledNodes(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.CountNSNodes = countNodes
|
||||
|
||||
// 离线节点数
|
||||
countOfflineNodes, err := models.SharedNSNodeDAO.CountAllOfflineNodes(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.CountOfflineNSNodes = countOfflineNodes
|
||||
|
||||
// 按小时统计
|
||||
var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
|
||||
var hourTo = timeutil.Format("YmdH")
|
||||
hourlyStats, err := nameservers.SharedNSRecordHourlyStatDAO.FindHourlyStats(tx, hourFrom, hourTo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, stat := range hourlyStats {
|
||||
result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeNSBoardResponse_HourlyTrafficStat{
|
||||
Hour: stat.Hour,
|
||||
Bytes: int64(stat.Bytes),
|
||||
CountRequests: int64(stat.CountRequests),
|
||||
})
|
||||
}
|
||||
|
||||
// 按天统计
|
||||
var dayFrom = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -14))
|
||||
var dayTo = timeutil.Format("Ymd")
|
||||
dailyStats, err := nameservers.SharedNSRecordHourlyStatDAO.FindDailyStats(tx, dayFrom, dayTo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, stat := range dailyStats {
|
||||
result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeNSBoardResponse_DailyTrafficStat{
|
||||
Day: stat.Day,
|
||||
Bytes: int64(stat.Bytes),
|
||||
CountRequests: int64(stat.CountRequests),
|
||||
})
|
||||
}
|
||||
|
||||
// 域名排行
|
||||
topDomainStats, err := nameservers.SharedNSRecordHourlyStatDAO.ListTopDomains(tx, 0, hourFrom, hourTo, 10)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, stat := range topDomainStats {
|
||||
domainName, err := nameservers.SharedNSDomainDAO.FindNSDomainName(tx, int64(stat.DomainId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(domainName) == 0 {
|
||||
continue
|
||||
}
|
||||
result.TopNSDomainStats = append(result.TopNSDomainStats, &pb.ComposeNSBoardResponse_DomainStat{
|
||||
NsDomainId: int64(stat.DomainId),
|
||||
NsDomainName: domainName,
|
||||
CountRequests: int64(stat.CountRequests),
|
||||
Bytes: int64(stat.Bytes),
|
||||
})
|
||||
}
|
||||
|
||||
// 节点排行
|
||||
topNodeStats, err := nameservers.SharedNSRecordHourlyStatDAO.ListTopNodes(tx, hourFrom, hourTo, 10)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, stat := range topNodeStats {
|
||||
nodeName, err := models.SharedNSNodeDAO.FindEnabledNSNodeName(tx, int64(stat.NodeId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodeName) == 0 {
|
||||
continue
|
||||
}
|
||||
result.TopNSNodeStats = append(result.TopNSNodeStats, &pb.ComposeNSBoardResponse_NodeStat{
|
||||
NsClusterId: int64(stat.ClusterId),
|
||||
NsNodeId: int64(stat.NodeId),
|
||||
NsNodeName: nodeName,
|
||||
CountRequests: int64(stat.CountRequests),
|
||||
Bytes: int64(stat.Bytes),
|
||||
})
|
||||
}
|
||||
|
||||
// CPU、内存、负载
|
||||
cpuValues, err := models.SharedNodeValueDAO.ListValuesForNSNodes(tx, nodeconfigs.NodeValueItemCPU, "usage", nodeconfigs.NodeValueRangeMinute)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range cpuValues {
|
||||
result.CpuNodeValues = append(result.CpuNodeValues, &pb.NodeValue{
|
||||
ValueJSON: v.Value,
|
||||
CreatedAt: int64(v.CreatedAt),
|
||||
})
|
||||
}
|
||||
|
||||
memoryValues, err := models.SharedNodeValueDAO.ListValuesForNSNodes(tx, nodeconfigs.NodeValueItemMemory, "usage", nodeconfigs.NodeValueRangeMinute)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range memoryValues {
|
||||
result.MemoryNodeValues = append(result.MemoryNodeValues, &pb.NodeValue{
|
||||
ValueJSON: v.Value,
|
||||
CreatedAt: int64(v.CreatedAt),
|
||||
})
|
||||
}
|
||||
|
||||
loadValues, err := models.SharedNodeValueDAO.ListValuesForNSNodes(tx, nodeconfigs.NodeValueItemLoad, "load1m", nodeconfigs.NodeValueRangeMinute)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range loadValues {
|
||||
result.LoadNodeValues = append(result.LoadNodeValues, &pb.NodeValue{
|
||||
ValueJSON: v.Value,
|
||||
CreatedAt: int64(v.CreatedAt),
|
||||
})
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ComposeNSUserBoard 组合用户看板数据
|
||||
func (this *NSService) ComposeNSUserBoard(ctx context.Context, req *pb.ComposeNSUserBoardRequest) (*pb.ComposeNSUserBoardResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
var result = &pb.ComposeNSUserBoardResponse{}
|
||||
|
||||
var tx = this.NullTx()
|
||||
countDomains, err := nameservers.SharedNSDomainDAO.CountAllEnabledDomains(tx, 0, req.UserId, 0, "", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.CountNSDomains = countDomains
|
||||
|
||||
countRecords, err := nameservers.SharedNSRecordDAO.CountAllUserRecords(tx, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.CountNSRecords = countRecords
|
||||
|
||||
countRoutes, err := nameservers.SharedNSRouteDAO.CountAllEnabledRoutes(tx, 0, 0, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.CountNSRoutes = countRoutes
|
||||
|
||||
// 用户套餐
|
||||
userPlan, err := nameservers.SharedNSUserPlanDAO.FindUserPlan(tx, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userPlan != nil {
|
||||
if userPlan.PlanId > 0 && userPlan.DayTo >= timeutil.Format("Ymd") {
|
||||
plan, err := nameservers.SharedNSPlanDAO.FindEnabledNSPlan(tx, int64(userPlan.PlanId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if plan != nil && plan.IsOn {
|
||||
result.NsUserPlan = &pb.NSUserPlan{
|
||||
Id: int64(userPlan.Id),
|
||||
NsPlanId: int64(userPlan.PlanId),
|
||||
DayFrom: userPlan.DayFrom,
|
||||
DayTo: userPlan.DayTo,
|
||||
PeriodUnit: userPlan.PeriodUnit,
|
||||
NsPlan: &pb.NSPlan{
|
||||
Id: int64(plan.Id),
|
||||
Name: plan.Name,
|
||||
IsOn: plan.IsOn,
|
||||
},
|
||||
User: nil,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 域名排行
|
||||
var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
|
||||
var hourTo = timeutil.Format("YmdH")
|
||||
topDomainStats, err := nameservers.SharedNSRecordHourlyStatDAO.ListTopDomains(tx, userId, hourFrom, hourTo, 10)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, stat := range topDomainStats {
|
||||
domainName, err := nameservers.SharedNSDomainDAO.FindNSDomainName(tx, int64(stat.DomainId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(domainName) == 0 {
|
||||
continue
|
||||
}
|
||||
result.TopNSDomainStats = append(result.TopNSDomainStats, &pb.ComposeNSUserBoardResponse_DomainStat{
|
||||
NsDomainId: int64(stat.DomainId),
|
||||
NsDomainName: domainName,
|
||||
CountRequests: int64(stat.CountRequests),
|
||||
Bytes: int64(stat.Bytes),
|
||||
})
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
//go:build plus
|
||||
|
||||
package nameservers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
// NSAccessLogService 访问日志相关服务
|
||||
type NSAccessLogService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateNSAccessLogs 创建访问日志
|
||||
func (this *NSAccessLogService) CreateNSAccessLogs(ctx context.Context, req *pb.CreateNSAccessLogsRequest) (*pb.CreateNSAccessLogsResponse, error) {
|
||||
// 校验请求
|
||||
_, _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeDNS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(req.NsAccessLogs) == 0 {
|
||||
return &pb.CreateNSAccessLogsResponse{}, nil
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
err = models.SharedNSAccessLogDAO.CreateNSAccessLogs(tx, req.NsAccessLogs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CreateNSAccessLogsResponse{}, nil
|
||||
}
|
||||
|
||||
// ListNSAccessLogs 列出单页访问日志
|
||||
func (this *NSAccessLogService) ListNSAccessLogs(ctx context.Context, req *pb.ListNSAccessLogsRequest) (*pb.ListNSAccessLogsResponse, error) {
|
||||
// 校验请求
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查服务ID
|
||||
if userId > 0 {
|
||||
// TODO 检查权限
|
||||
}
|
||||
|
||||
accessLogs, requestId, hasMore, err := models.SharedNSAccessLogDAO.ListAccessLogs(tx, req.RequestId, req.Size, req.Day, req.NsClusterId, req.NsNodeId, req.NsDomainId, req.NsRecordId, req.RecordType, req.Keyword, req.Reverse)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result = []*pb.NSAccessLog{}
|
||||
for _, accessLog := range accessLogs {
|
||||
a, err := accessLog.ToPB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 线路
|
||||
if len(a.NsRouteCodes) > 0 {
|
||||
for _, routeCode := range a.NsRouteCodes {
|
||||
route, err := nameservers.SharedNSRouteDAO.FindEnabledRouteWithCode(nil, routeCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if route != nil {
|
||||
a.NsRoutes = append(a.NsRoutes, &pb.NSRoute{
|
||||
Id: types.Int64(route.Id),
|
||||
IsOn: route.IsOn,
|
||||
Name: route.Name,
|
||||
Code: routeCode,
|
||||
NsCluster: nil,
|
||||
NsDomain: nil,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = append(result, a)
|
||||
}
|
||||
|
||||
return &pb.ListNSAccessLogsResponse{
|
||||
NsAccessLogs: result,
|
||||
HasMore: hasMore,
|
||||
RequestId: requestId,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindNSAccessLog 查找单个日志
|
||||
func (this *NSAccessLogService) FindNSAccessLog(ctx context.Context, req *pb.FindNSAccessLogRequest) (*pb.FindNSAccessLogResponse, error) {
|
||||
// 校验请求
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
accessLog, err := models.SharedNSAccessLogDAO.FindAccessLogWithRequestId(tx, req.RequestId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if accessLog == nil {
|
||||
return &pb.FindNSAccessLogResponse{NsAccessLog: nil}, nil
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
// TODO
|
||||
}
|
||||
|
||||
a, err := accessLog.ToPB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.FindNSAccessLogResponse{NsAccessLog: a}, nil
|
||||
}
|
||||
679
EdgeAPI/internal/rpc/services/nameservers/service_ns_cluster.go
Normal file
679
EdgeAPI/internal/rpc/services/nameservers/service_ns_cluster.go
Normal file
@@ -0,0 +1,679 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build plus
|
||||
|
||||
package nameservers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
// NSClusterService 域名服务集群相关服务
|
||||
type NSClusterService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateNSCluster 创建集群
|
||||
func (this *NSClusterService) CreateNSCluster(ctx context.Context, req *pb.CreateNSClusterRequest) (*pb.CreateNSClusterResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tx = this.NullTx()
|
||||
|
||||
// SOA
|
||||
var soaConfig = dnsconfigs.DefaultNSSOAConfig()
|
||||
if len(req.SoaJSON) > 0 {
|
||||
err = json.Unmarshal(req.SoaJSON, soaConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = soaConfig.Init()
|
||||
if err != nil {
|
||||
return nil, errors.New("validate SOA config failed: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// 校验管理员邮箱
|
||||
if len(req.Email) == 0 {
|
||||
return nil, errors.New("required 'email'")
|
||||
}
|
||||
if !utils.ValidateEmail(req.Email) {
|
||||
return nil, errors.New("invalid email format '" + req.Email + "'")
|
||||
}
|
||||
|
||||
// 校验访问日志配置
|
||||
var accessLogRef = &dnsconfigs.NSAccessLogRef{}
|
||||
if len(req.AccessLogJSON) > 0 {
|
||||
err = json.Unmarshal(req.AccessLogJSON, accessLogRef)
|
||||
if err != nil {
|
||||
return nil, errors.New("invalid accessLogJSON: " + err.Error())
|
||||
}
|
||||
err = accessLogRef.Init()
|
||||
if err != nil {
|
||||
return nil, errors.New("validate accessLogJSON failed: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
clusterId, err := models.SharedNSClusterDAO.CreateCluster(tx, req.Name, req.Email, req.AccessLogJSON, req.Hosts, soaConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.CreateNSClusterResponse{NsClusterId: clusterId}, nil
|
||||
}
|
||||
|
||||
// UpdateNSCluster 修改集群
|
||||
func (this *NSClusterService) UpdateNSCluster(ctx context.Context, req *pb.UpdateNSClusterRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 校验管理员邮箱
|
||||
if len(req.Email) == 0 {
|
||||
return nil, errors.New("required 'email'")
|
||||
}
|
||||
if !utils.ValidateEmail(req.Email) {
|
||||
return nil, errors.New("invalid email format '" + req.Email + "'")
|
||||
}
|
||||
|
||||
err = models.SharedNSClusterDAO.UpdateCluster(tx, req.NsClusterId, req.Name, req.Email, req.Hosts, req.IsOn, req.TimeZone, req.AutoRemoteStart, req.DetectAgents, req.CheckingPorts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSClusterAccessLog 查找集群访问日志配置
|
||||
func (this *NSClusterService) FindNSClusterAccessLog(ctx context.Context, req *pb.FindNSClusterAccessLogRequest) (*pb.FindNSClusterAccessLogResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
accessLogJSON, err := models.SharedNSClusterDAO.FindClusterAccessLog(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.FindNSClusterAccessLogResponse{AccessLogJSON: accessLogJSON}, nil
|
||||
}
|
||||
|
||||
// UpdateNSClusterAccessLog 修改集群访问日志配置
|
||||
func (this *NSClusterService) UpdateNSClusterAccessLog(ctx context.Context, req *pb.UpdateNSClusterAccessLogRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 校验访问日志配置
|
||||
var accessLogRef = &dnsconfigs.NSAccessLogRef{}
|
||||
if len(req.AccessLogJSON) > 0 {
|
||||
err = json.Unmarshal(req.AccessLogJSON, accessLogRef)
|
||||
if err != nil {
|
||||
return nil, errors.New("invalid accessLogJSON: " + err.Error())
|
||||
}
|
||||
err = accessLogRef.Init()
|
||||
if err != nil {
|
||||
return nil, errors.New("validate accessLogJSON failed: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedNSClusterDAO.UpdateClusterAccessLog(tx, req.NsClusterId, req.AccessLogJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// DeleteNSCluster 删除集群
|
||||
func (this *NSClusterService) DeleteNSCluster(ctx context.Context, req *pb.DeleteNSCluster) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedNSClusterDAO.DisableNSCluster(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 删除任务
|
||||
err = models.SharedNodeTaskDAO.DeleteAllClusterTasks(tx, nodeconfigs.NodeRoleDNS, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSCluster 查找单个可用集群信息
|
||||
func (this *NSClusterService) FindNSCluster(ctx context.Context, req *pb.FindNSClusterRequest) (*pb.FindNSClusterResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tx = this.NullTx()
|
||||
cluster, err := models.SharedNSClusterDAO.FindEnabledNSCluster(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cluster == nil {
|
||||
return &pb.FindNSClusterResponse{NsCluster: nil}, nil
|
||||
}
|
||||
return &pb.FindNSClusterResponse{
|
||||
NsCluster: &pb.NSCluster{
|
||||
Id: int64(cluster.Id),
|
||||
IsOn: cluster.IsOn,
|
||||
Name: cluster.Name,
|
||||
Email: cluster.Email,
|
||||
Hosts: cluster.DecodeHosts(),
|
||||
InstallDir: cluster.InstallDir,
|
||||
TcpJSON: cluster.Tcp,
|
||||
TlsJSON: cluster.Tls,
|
||||
UdpJSON: cluster.Udp,
|
||||
DohJSON: cluster.Doh,
|
||||
TimeZone: cluster.TimeZone,
|
||||
AutoRemoteStart: cluster.AutoRemoteStart,
|
||||
AnswerJSON: cluster.Answer,
|
||||
SoaJSON: cluster.Soa,
|
||||
DetectAgents: cluster.DetectAgents,
|
||||
CheckingPorts: cluster.CheckingPorts,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CountAllNSClusters 计算所有可用集群的数量
|
||||
func (this *NSClusterService) CountAllNSClusters(ctx context.Context, req *pb.CountAllNSClustersRequest) (*pb.RPCCountResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tx = this.NullTx()
|
||||
count, err := models.SharedNSClusterDAO.CountAllEnabledClusters(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.SuccessCount(count)
|
||||
}
|
||||
|
||||
// ListNSClusters 列出单页可用集群
|
||||
func (this *NSClusterService) ListNSClusters(ctx context.Context, req *pb.ListNSClustersRequest) (*pb.ListNSClustersResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tx = this.NullTx()
|
||||
clusters, err := models.SharedNSClusterDAO.ListEnabledClusters(tx, req.Offset, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbClusters = []*pb.NSCluster{}
|
||||
for _, cluster := range clusters {
|
||||
pbClusters = append(pbClusters, &pb.NSCluster{
|
||||
Id: int64(cluster.Id),
|
||||
IsOn: cluster.IsOn,
|
||||
Name: cluster.Name,
|
||||
Hosts: cluster.DecodeHosts(),
|
||||
InstallDir: cluster.InstallDir,
|
||||
})
|
||||
}
|
||||
return &pb.ListNSClustersResponse{NsClusters: pbClusters}, nil
|
||||
}
|
||||
|
||||
// FindAllNSClusters 查找所有可用集群
|
||||
func (this *NSClusterService) FindAllNSClusters(ctx context.Context, req *pb.FindAllNSClustersRequest) (*pb.FindAllNSClustersResponse, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tx = this.NullTx()
|
||||
clusters, err := models.SharedNSClusterDAO.FindAllEnabledClusters(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbClusters = []*pb.NSCluster{}
|
||||
for _, cluster := range clusters {
|
||||
pbClusters = append(pbClusters, &pb.NSCluster{
|
||||
Id: int64(cluster.Id),
|
||||
IsOn: cluster.IsOn,
|
||||
Name: cluster.Name,
|
||||
InstallDir: cluster.InstallDir,
|
||||
})
|
||||
}
|
||||
return &pb.FindAllNSClustersResponse{NsClusters: pbClusters}, nil
|
||||
}
|
||||
|
||||
// UpdateNSClusterRecursionConfig 设置递归DNS配置
|
||||
func (this *NSClusterService) UpdateNSClusterRecursionConfig(ctx context.Context, req *pb.UpdateNSClusterRecursionConfigRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 校验配置
|
||||
var config = &dnsconfigs.NSRecursionConfig{}
|
||||
err = json.Unmarshal(req.RecursionJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedNSClusterDAO.UpdateRecursion(tx, req.NsClusterId, req.RecursionJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSClusterRecursionConfig 读取递归DNS配置
|
||||
func (this *NSClusterService) FindNSClusterRecursionConfig(ctx context.Context, req *pb.FindNSClusterRecursionConfigRequest) (*pb.FindNSClusterRecursionConfigResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
recursion, err := models.SharedNSClusterDAO.FindClusterRecursion(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.FindNSClusterRecursionConfigResponse{
|
||||
RecursionJSON: recursion,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindNSClusterTCPConfig 查找集群的TCP设置
|
||||
func (this *NSClusterService) FindNSClusterTCPConfig(ctx context.Context, req *pb.FindNSClusterTCPConfigRequest) (*pb.FindNSClusterTCPConfigResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
tcpJSON, err := models.SharedNSClusterDAO.FindClusterTCP(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindNSClusterTCPConfigResponse{
|
||||
TcpJSON: tcpJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNSClusterTCP 修改集群的TCP设置
|
||||
func (this *NSClusterService) UpdateNSClusterTCP(ctx context.Context, req *pb.UpdateNSClusterTCPRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config = &serverconfigs.TCPProtocolConfig{}
|
||||
err = json.Unmarshal(req.TcpJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedNSClusterDAO.UpdateClusterTCP(tx, req.NsClusterId, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSClusterTLSConfig 查找集群的TLS设置
|
||||
func (this *NSClusterService) FindNSClusterTLSConfig(ctx context.Context, req *pb.FindNSClusterTLSConfigRequest) (*pb.FindNSClusterTLSConfigResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
tlsJSON, err := models.SharedNSClusterDAO.FindClusterTLS(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindNSClusterTLSConfigResponse{
|
||||
TlsJSON: tlsJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNSClusterTLS 修改集群的TLS设置
|
||||
func (this *NSClusterService) UpdateNSClusterTLS(ctx context.Context, req *pb.UpdateNSClusterTLSRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config = &serverconfigs.TLSProtocolConfig{}
|
||||
err = json.Unmarshal(req.TlsJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedNSClusterDAO.UpdateClusterTLS(tx, req.NsClusterId, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSClusterUDPConfig 查找集群的UDP设置
|
||||
func (this *NSClusterService) FindNSClusterUDPConfig(ctx context.Context, req *pb.FindNSClusterUDPConfigRequest) (*pb.FindNSClusterUDPConfigResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
udpJSON, err := models.SharedNSClusterDAO.FindClusterUDP(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindNSClusterUDPConfigResponse{
|
||||
UdpJSON: udpJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNSClusterUDP 修改集群的UDP设置
|
||||
func (this *NSClusterService) UpdateNSClusterUDP(ctx context.Context, req *pb.UpdateNSClusterUDPRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config = &serverconfigs.UDPProtocolConfig{}
|
||||
err = json.Unmarshal(req.UdpJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedNSClusterDAO.UpdateClusterUDP(tx, req.NsClusterId, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSClusterDoHConfig 查找集群的DoH设置
|
||||
func (this *NSClusterService) FindNSClusterDoHConfig(ctx context.Context, req *pb.FindNSClusterDoHConfigRequest) (*pb.FindNSClusterDoHConfigResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
dohJSON, err := models.SharedNSClusterDAO.FindClusterDoH(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindNSClusterDoHConfigResponse{
|
||||
DohJSON: dohJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNSClusterDoH 修改集群的DoH设置
|
||||
func (this *NSClusterService) UpdateNSClusterDoH(ctx context.Context, req *pb.UpdateNSClusterDoHRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config = dnsconfigs.NewNSDoHConfig()
|
||||
err = json.Unmarshal(req.DohJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedNSClusterDAO.UpdateClusterDoH(tx, req.NsClusterId, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// CountAllNSClustersWithSSLCertId 计算使用某个SSL证书的集群数量
|
||||
func (this *NSClusterService) CountAllNSClustersWithSSLCertId(ctx context.Context, req *pb.CountAllNSClustersWithSSLCertIdRequest) (*pb.RPCCountResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
policyIds, err := models.SharedSSLPolicyDAO.FindAllEnabledPolicyIdsWithCertId(tx, req.SslCertId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(policyIds) == 0 {
|
||||
return this.SuccessCount(0)
|
||||
}
|
||||
|
||||
count, err := models.SharedNSClusterDAO.CountAllClustersWithSSLPolicyIds(tx, policyIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.SuccessCount(count)
|
||||
}
|
||||
|
||||
// FindNSClusterDDoSProtection 获取集群的DDoS设置
|
||||
func (this *NSClusterService) FindNSClusterDDoSProtection(ctx context.Context, req *pb.FindNSClusterDDoSProtectionRequest) (*pb.FindNSClusterDDoSProtectionResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx *dbs.Tx
|
||||
ddosProtection, err := models.SharedNSClusterDAO.FindClusterDDoSProtection(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ddosProtection == nil {
|
||||
ddosProtection = ddosconfigs.DefaultProtectionConfig()
|
||||
}
|
||||
ddosProtectionJSON, err := json.Marshal(ddosProtection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result = &pb.FindNSClusterDDoSProtectionResponse{
|
||||
DdosProtectionJSON: ddosProtectionJSON,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UpdateNSClusterDDoSProtection 修改集群的DDoS设置
|
||||
func (this *NSClusterService) UpdateNSClusterDDoSProtection(ctx context.Context, req *pb.UpdateNSClusterDDoSProtectionRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ddosProtection = &ddosconfigs.ProtectionConfig{}
|
||||
err = json.Unmarshal(req.DdosProtectionJSON, ddosProtection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx *dbs.Tx
|
||||
err = models.SharedNSClusterDAO.UpdateClusterDDoSProtection(tx, req.NsClusterId, ddosProtection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSClusterHosts 查找NS集群的主机地址
|
||||
func (this *NSClusterService) FindNSClusterHosts(ctx context.Context, req *pb.FindNSClusterHostsRequest) (*pb.FindNSClusterHostsResponse, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
hosts, err := models.SharedNSClusterDAO.FindClusterHosts(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindNSClusterHostsResponse{
|
||||
Hosts: hosts,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindAvailableNSHostsForUser 查找用户可以使用的主机地址
|
||||
func (this *NSClusterService) FindAvailableNSHostsForUser(ctx context.Context, req *pb.FindAvailableNSHostsForUserRequest) (*pb.FindAvailableNSHostsForUserResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
if req.UserId <= 0 {
|
||||
return &pb.FindAvailableNSHostsForUserResponse{
|
||||
Hosts: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 所属集群
|
||||
var tx = this.NullTx()
|
||||
userConfig, err := models.SharedSysSettingDAO.ReadNSUserConfig(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userConfig == nil || userConfig.DefaultClusterId <= 0 {
|
||||
return &pb.FindAvailableNSHostsForUserResponse{
|
||||
Hosts: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
hosts, err := models.SharedNSClusterDAO.FindClusterHosts(tx, userConfig.DefaultClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindAvailableNSHostsForUserResponse{
|
||||
Hosts: hosts,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindNSClusterAnswerConfig 查找应答模式
|
||||
func (this *NSClusterService) FindNSClusterAnswerConfig(ctx context.Context, req *pb.FindNSClusterAnswerConfigRequest) (*pb.FindNSClusterAnswerConfigResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
config, err := models.SharedNSClusterDAO.FindClusterAnswer(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configJSON, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.FindNSClusterAnswerConfigResponse{
|
||||
AnswerJSON: configJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNSClusterAnswerConfig 设置应答模式
|
||||
func (this *NSClusterService) UpdateNSClusterAnswerConfig(ctx context.Context, req *pb.UpdateNSClusterAnswerConfigRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config = dnsconfigs.DefaultNSAnswerConfig()
|
||||
if len(req.AnswerJSON) > 0 {
|
||||
err = json.Unmarshal(req.AnswerJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedNSClusterDAO.UpdateClusterAnswer(tx, req.NsClusterId, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSClusterSOAConfig 查询SOA配置
|
||||
func (this *NSClusterService) FindNSClusterSOAConfig(ctx context.Context, req *pb.FindNSClusterSOAConfigRequest) (*pb.FindNSClusterSOAConfigResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
config, err := models.SharedNSClusterDAO.FindClusterSOA(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configJSON, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.FindNSClusterSOAConfigResponse{
|
||||
SoaJSON: configJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNSClusterSOAConfig 修改SOA配置
|
||||
func (this *NSClusterService) UpdateNSClusterSOAConfig(ctx context.Context, req *pb.UpdateNSClusterSOAConfigRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config = dnsconfigs.DefaultNSSOAConfig()
|
||||
if len(req.SoaJSON) > 0 {
|
||||
err = json.Unmarshal(req.SoaJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedNSClusterDAO.UpdateClusterSOA(tx, req.NsClusterId, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
1127
EdgeAPI/internal/rpc/services/nameservers/service_ns_domain.go
Normal file
1127
EdgeAPI/internal/rpc/services/nameservers/service_ns_domain.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,194 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build plus
|
||||
|
||||
package nameservers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
// NSDomainGroupService 域名分组服务
|
||||
type NSDomainGroupService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateNSDomainGroup 创建分组
|
||||
func (this *NSDomainGroupService) CreateNSDomainGroup(ctx context.Context, req *pb.CreateNSDomainGroupRequest) (*pb.CreateNSDomainGroupResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
groupId, err := nameservers.SharedNSDomainGroupDAO.CreateGroup(tx, userId, req.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CreateNSDomainGroupResponse{
|
||||
NsDomainGroupId: groupId,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNSDomainGroup 修改分组
|
||||
func (this *NSDomainGroupService) UpdateNSDomainGroup(ctx context.Context, req *pb.UpdateNSDomainGroupRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainGroupDAO.CheckUserGroup(tx, userId, req.NsDomainGroupId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSDomainGroupDAO.UpdateGroup(tx, req.NsDomainGroupId, req.Name, req.IsOn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// DeleteNSDomainGroup 删除分组
|
||||
func (this *NSDomainGroupService) DeleteNSDomainGroup(ctx context.Context, req *pb.DeleteNSDomainGroupRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainGroupDAO.CheckUserGroup(tx, userId, req.NsDomainGroupId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSDomainGroupDAO.DisableNSDomainGroup(tx, req.NsDomainGroupId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindAllNSDomainGroups 查询所有分组
|
||||
func (this *NSDomainGroupService) FindAllNSDomainGroups(ctx context.Context, req *pb.FindAllNSDomainGroupsRequest) (*pb.FindAllNSDomainGroupsResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
groups, err := nameservers.SharedNSDomainGroupDAO.FindAllGroups(tx, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbGroups = []*pb.NSDomainGroup{}
|
||||
for _, group := range groups {
|
||||
pbGroups = append(pbGroups, &pb.NSDomainGroup{
|
||||
Id: int64(group.Id),
|
||||
Name: group.Name,
|
||||
IsOn: group.IsOn,
|
||||
UserId: int64(group.UserId),
|
||||
})
|
||||
}
|
||||
return &pb.FindAllNSDomainGroupsResponse{
|
||||
NsDomainGroups: pbGroups,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CountAllAvailableNSDomainGroups 查询可用分组数量
|
||||
func (this *NSDomainGroupService) CountAllAvailableNSDomainGroups(ctx context.Context, req *pb.CountAllAvailableNSDomainGroupsRequest) (*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()
|
||||
count, err := nameservers.SharedNSDomainGroupDAO.CountAllAvailableGroups(tx, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.SuccessCount(count)
|
||||
}
|
||||
|
||||
// FindAllAvailableNSDomainGroups 查询所有分组
|
||||
func (this *NSDomainGroupService) FindAllAvailableNSDomainGroups(ctx context.Context, req *pb.FindAllAvailableNSDomainGroupsRequest) (*pb.FindAllAvailableNSDomainGroupsResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
groups, err := nameservers.SharedNSDomainGroupDAO.FindAllAvailableGroups(tx, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbGroups = []*pb.NSDomainGroup{}
|
||||
for _, group := range groups {
|
||||
pbGroups = append(pbGroups, &pb.NSDomainGroup{
|
||||
Id: int64(group.Id),
|
||||
Name: group.Name,
|
||||
IsOn: group.IsOn,
|
||||
UserId: int64(group.UserId),
|
||||
})
|
||||
}
|
||||
return &pb.FindAllAvailableNSDomainGroupsResponse{
|
||||
NsDomainGroups: pbGroups,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindNSDomainGroup 查找单个分组
|
||||
func (this *NSDomainGroupService) FindNSDomainGroup(ctx context.Context, req *pb.FindNSDomainGroupRequest) (*pb.FindNSDomainGroupResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
group, err := nameservers.SharedNSDomainGroupDAO.FindEnabledNSDomainGroup(tx, req.NsDomainGroupId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if group == nil {
|
||||
return &pb.FindNSDomainGroupResponse{
|
||||
NsDomainGroup: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if int64(group.UserId) != userId {
|
||||
return &pb.FindNSDomainGroupResponse{
|
||||
NsDomainGroup: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &pb.FindNSDomainGroupResponse{
|
||||
NsDomainGroup: &pb.NSDomainGroup{
|
||||
Id: int64(group.Id),
|
||||
Name: group.Name,
|
||||
IsOn: group.IsOn,
|
||||
UserId: int64(group.UserId),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
225
EdgeAPI/internal/rpc/services/nameservers/service_ns_key.go
Normal file
225
EdgeAPI/internal/rpc/services/nameservers/service_ns_key.go
Normal file
@@ -0,0 +1,225 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build plus
|
||||
|
||||
package nameservers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
// NSKeyService NS密钥相关服务
|
||||
type NSKeyService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateNSKey 创建密钥
|
||||
func (this *NSKeyService) CreateNSKey(ctx context.Context, req *pb.CreateNSKeyRequest) (*pb.CreateNSKeyResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查用户权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainDAO.CheckUserDomain(tx, userId, req.NsDomainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
keyId, err := nameservers.SharedNSKeyDAO.CreateKey(tx, req.NsDomainId, req.NsZoneId, req.Name, req.Algo, req.Secret, req.SecretType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.CreateNSKeyResponse{NsKeyId: keyId}, nil
|
||||
}
|
||||
|
||||
// UpdateNSKey 修改密钥
|
||||
func (this *NSKeyService) UpdateNSKey(ctx context.Context, req *pb.UpdateNSKeyRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查用户权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSKeyDAO.CheckUserKey(tx, userId, req.NsKeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSKeyDAO.UpdateKey(tx, req.NsKeyId, req.Name, req.Algo, req.Secret, req.SecretType, req.IsOn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// DeleteNSKey 删除密钥
|
||||
func (this *NSKeyService) DeleteNSKey(ctx context.Context, req *pb.DeleteNSKeyRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查用户权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSKeyDAO.CheckUserKey(tx, userId, req.NsKeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSKeyDAO.DisableNSKey(tx, req.NsKeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSKey 查找单个密钥
|
||||
func (this *NSKeyService) FindNSKey(ctx context.Context, req *pb.FindNSKeyRequest) (*pb.FindNSKeyResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查用户权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSKeyDAO.CheckUserKey(tx, userId, req.NsKeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
key, err := nameservers.SharedNSKeyDAO.FindEnabledNSKey(tx, req.NsKeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if key == nil {
|
||||
return &pb.FindNSKeyResponse{NsKey: nil}, nil
|
||||
}
|
||||
return &pb.FindNSKeyResponse{
|
||||
NsKey: &pb.NSKey{
|
||||
Id: int64(key.Id),
|
||||
IsOn: key.IsOn,
|
||||
Name: key.Name,
|
||||
Algo: key.Algo,
|
||||
Secret: key.Secret,
|
||||
SecretType: key.SecretType,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CountAllNSKeys 计算密钥数量
|
||||
func (this *NSKeyService) CountAllNSKeys(ctx context.Context, req *pb.CountAllNSKeysRequest) (*pb.RPCCountResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查用户权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainDAO.CheckUserDomain(tx, userId, req.NsDomainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
count, err := nameservers.SharedNSKeyDAO.CountEnabledKeys(tx, req.NsDomainId, req.NsZoneId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.SuccessCount(count)
|
||||
}
|
||||
|
||||
// ListNSKeys 列出单页密钥
|
||||
func (this *NSKeyService) ListNSKeys(ctx context.Context, req *pb.ListNSKeysRequest) (*pb.ListNSKeysResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查用户权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainDAO.CheckUserDomain(tx, userId, req.NsDomainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
keys, err := nameservers.SharedNSKeyDAO.ListEnabledKeys(tx, req.NsDomainId, req.NsZoneId, req.Offset, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbKeys = []*pb.NSKey{}
|
||||
for _, key := range keys {
|
||||
pbKeys = append(pbKeys, &pb.NSKey{
|
||||
Id: int64(key.Id),
|
||||
IsOn: key.IsOn,
|
||||
Name: key.Name,
|
||||
Algo: key.Algo,
|
||||
Secret: key.Secret,
|
||||
SecretType: key.SecretType,
|
||||
})
|
||||
}
|
||||
return &pb.ListNSKeysResponse{NsKeys: pbKeys}, nil
|
||||
}
|
||||
|
||||
// ListNSKeysAfterVersion 根据版本列出一组密钥
|
||||
func (this *NSKeyService) ListNSKeysAfterVersion(ctx context.Context, req *pb.ListNSKeysAfterVersionRequest) (*pb.ListNSKeysAfterVersionResponse, error) {
|
||||
_, err := this.ValidateNSNode(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
if req.Size <= 0 {
|
||||
req.Size = 2000
|
||||
}
|
||||
keys, err := nameservers.SharedNSKeyDAO.ListKeysAfterVersion(tx, req.Version, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbKeys = []*pb.NSKey{}
|
||||
for _, key := range keys {
|
||||
var pbDomain *pb.NSDomain
|
||||
var pbZone *pb.NSZone
|
||||
|
||||
if key.DomainId > 0 {
|
||||
pbDomain = &pb.NSDomain{Id: int64(key.DomainId)}
|
||||
}
|
||||
if key.ZoneId > 0 {
|
||||
pbZone = &pb.NSZone{Id: int64(key.ZoneId)}
|
||||
}
|
||||
|
||||
pbKeys = append(pbKeys, &pb.NSKey{
|
||||
Id: int64(key.Id),
|
||||
IsOn: key.IsOn,
|
||||
Name: "",
|
||||
Algo: key.Algo,
|
||||
Secret: key.Secret,
|
||||
SecretType: key.SecretType,
|
||||
IsDeleted: key.State == nameservers.NSKeyStateDisabled,
|
||||
Version: int64(key.Version),
|
||||
NsDomain: pbDomain,
|
||||
NsZone: pbZone,
|
||||
})
|
||||
}
|
||||
return &pb.ListNSKeysAfterVersionResponse{NsKeys: pbKeys}, nil
|
||||
}
|
||||
740
EdgeAPI/internal/rpc/services/nameservers/service_ns_node.go
Normal file
740
EdgeAPI/internal/rpc/services/nameservers/service_ns_node.go
Normal file
@@ -0,0 +1,740 @@
|
||||
// Copyright 2021-2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build plus
|
||||
|
||||
package nameservers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/installers"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NSNodeService 域名服务器节点服务
|
||||
type NSNodeService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// FindAllNSNodesWithNSClusterId 根据集群查找所有节点
|
||||
func (this *NSNodeService) FindAllNSNodesWithNSClusterId(ctx context.Context, req *pb.FindAllNSNodesWithNSClusterIdRequest) (*pb.FindAllNSNodesWithNSClusterIdResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
nodes, err := models.SharedNSNodeDAO.FindAllEnabledNodesWithClusterId(tx, req.NsClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pbNodes := []*pb.NSNode{}
|
||||
for _, node := range nodes {
|
||||
pbNodes = append(pbNodes, &pb.NSNode{
|
||||
Id: int64(node.Id),
|
||||
Name: node.Name,
|
||||
IsOn: node.IsOn,
|
||||
UniqueId: node.UniqueId,
|
||||
Secret: node.Secret,
|
||||
IsInstalled: node.IsInstalled,
|
||||
InstallDir: node.InstallDir,
|
||||
IsUp: node.IsUp,
|
||||
ConnectedAPINodeIds: node.DecodeConnectedAPINodes(),
|
||||
NsCluster: nil,
|
||||
})
|
||||
}
|
||||
return &pb.FindAllNSNodesWithNSClusterIdResponse{NsNodes: pbNodes}, nil
|
||||
}
|
||||
|
||||
// CountAllNSNodes 所有可用的节点数量
|
||||
func (this *NSNodeService) CountAllNSNodes(ctx context.Context, req *pb.CountAllNSNodesRequest) (*pb.RPCCountResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
count, err := models.SharedNSNodeDAO.CountAllEnabledNodes(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.SuccessCount(count)
|
||||
}
|
||||
|
||||
// CountAllNSNodesMatch 计算匹配的节点数量
|
||||
func (this *NSNodeService) CountAllNSNodesMatch(ctx context.Context, req *pb.CountAllNSNodesMatchRequest) (*pb.RPCCountResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
count, err := models.SharedNSNodeDAO.CountAllEnabledNodesMatch(tx, req.NsClusterId, configutils.ToBoolState(req.InstallState), configutils.ToBoolState(req.ActiveState), req.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.SuccessCount(count)
|
||||
}
|
||||
|
||||
// ListNSNodesMatch 列出单页节点
|
||||
func (this *NSNodeService) ListNSNodesMatch(ctx context.Context, req *pb.ListNSNodesMatchRequest) (*pb.ListNSNodesMatchResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
nodes, err := models.SharedNSNodeDAO.ListAllEnabledNodesMatch(tx, req.NsClusterId, configutils.ToBoolState(req.InstallState), configutils.ToBoolState(req.ActiveState), req.Keyword, req.Offset, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pbNodes := []*pb.NSNode{}
|
||||
for _, node := range nodes {
|
||||
// 安装信息
|
||||
installStatus, err := node.DecodeInstallStatus()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
installStatusResult := &pb.NodeInstallStatus{}
|
||||
if installStatus != nil {
|
||||
installStatusResult = &pb.NodeInstallStatus{
|
||||
IsRunning: installStatus.IsRunning,
|
||||
IsFinished: installStatus.IsFinished,
|
||||
IsOk: installStatus.IsOk,
|
||||
Error: installStatus.Error,
|
||||
ErrorCode: installStatus.ErrorCode,
|
||||
UpdatedAt: installStatus.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
pbNodes = append(pbNodes, &pb.NSNode{
|
||||
Id: int64(node.Id),
|
||||
Name: node.Name,
|
||||
IsOn: node.IsOn,
|
||||
UniqueId: node.UniqueId,
|
||||
Secret: node.Secret,
|
||||
IsActive: node.IsActive,
|
||||
IsInstalled: node.IsInstalled,
|
||||
InstallDir: node.InstallDir,
|
||||
IsUp: node.IsUp,
|
||||
StatusJSON: node.Status,
|
||||
InstallStatus: installStatusResult,
|
||||
NsCluster: nil,
|
||||
})
|
||||
}
|
||||
return &pb.ListNSNodesMatchResponse{NsNodes: pbNodes}, nil
|
||||
}
|
||||
|
||||
// CountAllUpgradeNSNodesWithNSClusterId 计算需要升级的节点数量
|
||||
func (this *NSNodeService) CountAllUpgradeNSNodesWithNSClusterId(ctx context.Context, req *pb.CountAllUpgradeNSNodesWithNSClusterIdRequest) (*pb.RPCCountResponse, error) {
|
||||
// 校验请求
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
deployFiles := installers.SharedDeployManager.LoadNSNodeFiles()
|
||||
total := int64(0)
|
||||
for _, deployFile := range deployFiles {
|
||||
count, err := models.SharedNSNodeDAO.CountAllLowerVersionNodesWithClusterId(tx, req.NsClusterId, deployFile.OS, deployFile.Arch, deployFile.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
total += count
|
||||
}
|
||||
|
||||
return this.SuccessCount(total)
|
||||
}
|
||||
|
||||
// CreateNSNode 创建节点
|
||||
func (this *NSNodeService) CreateNSNode(ctx context.Context, req *pb.CreateNSNodeRequest) (*pb.CreateNSNodeResponse, error) {
|
||||
adminId, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
nodeId, err := models.SharedNSNodeDAO.CreateNode(tx, adminId, req.Name, req.NodeClusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 增加认证相关
|
||||
if req.NodeLogin != nil {
|
||||
_, err = models.SharedNodeLoginDAO.CreateNodeLogin(tx, nodeconfigs.NodeRoleDNS, nodeId, req.NodeLogin.Name, req.NodeLogin.Type, req.NodeLogin.Params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.CreateNSNodeResponse{
|
||||
NsNodeId: nodeId,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteNSNode 删除节点
|
||||
func (this *NSNodeService) DeleteNSNode(ctx context.Context, req *pb.DeleteNSNodeRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
err = models.SharedNSNodeDAO.DisableNSNode(tx, req.NsNodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 删除任务
|
||||
err = models.SharedNodeTaskDAO.DeleteNodeTasks(tx, nodeconfigs.NodeRoleDNS, req.NsNodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSNode 查询单个节点信息
|
||||
func (this *NSNodeService) FindNSNode(ctx context.Context, req *pb.FindNSNodeRequest) (*pb.FindNSNodeResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
node, err := models.SharedNSNodeDAO.FindEnabledNSNode(tx, req.NsNodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if node == nil {
|
||||
return &pb.FindNSNodeResponse{NsNode: nil}, nil
|
||||
}
|
||||
|
||||
// 集群信息
|
||||
clusterName, err := models.SharedNSClusterDAO.FindEnabledNSClusterName(tx, int64(node.ClusterId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 认证信息
|
||||
login, err := models.SharedNodeLoginDAO.FindEnabledNodeLoginWithNodeId(tx, nodeconfigs.NodeRoleDNS, req.NsNodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var respLogin *pb.NodeLogin = nil
|
||||
if login != nil {
|
||||
respLogin = &pb.NodeLogin{
|
||||
Id: int64(login.Id),
|
||||
Name: login.Name,
|
||||
Type: login.Type,
|
||||
Params: login.Params,
|
||||
}
|
||||
}
|
||||
|
||||
// 安装信息
|
||||
installStatus, err := node.DecodeInstallStatus()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var installStatusResult = &pb.NodeInstallStatus{}
|
||||
if installStatus != nil {
|
||||
installStatusResult = &pb.NodeInstallStatus{
|
||||
IsRunning: installStatus.IsRunning,
|
||||
IsFinished: installStatus.IsFinished,
|
||||
IsOk: installStatus.IsOk,
|
||||
Error: installStatus.Error,
|
||||
ErrorCode: installStatus.ErrorCode,
|
||||
UpdatedAt: installStatus.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindNSNodeResponse{NsNode: &pb.NSNode{
|
||||
Id: int64(node.Id),
|
||||
Name: node.Name,
|
||||
StatusJSON: node.Status,
|
||||
UniqueId: node.UniqueId,
|
||||
Secret: node.Secret,
|
||||
IsInstalled: node.IsInstalled,
|
||||
InstallDir: node.InstallDir,
|
||||
ApiNodeAddrsJSON: node.ApiNodeAddrs,
|
||||
NsCluster: &pb.NSCluster{
|
||||
Id: int64(node.ClusterId),
|
||||
Name: clusterName,
|
||||
},
|
||||
InstallStatus: installStatusResult,
|
||||
IsOn: node.IsOn,
|
||||
IsActive: node.IsActive,
|
||||
NodeLogin: respLogin,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
// UpdateNSNode 修改节点
|
||||
func (this *NSNodeService) UpdateNSNode(ctx context.Context, req *pb.UpdateNSNodeRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
err = models.SharedNSNodeDAO.UpdateNode(tx, req.NsNodeId, req.Name, req.NsClusterId, req.IsOn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 登录信息
|
||||
if req.NodeLogin == nil {
|
||||
err = models.SharedNodeLoginDAO.DisableNodeLogins(tx, nodeconfigs.NodeRoleDNS, req.NsNodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if req.NodeLogin.Id > 0 {
|
||||
err = models.SharedNodeLoginDAO.UpdateNodeLogin(tx, req.NodeLogin.Id, req.NodeLogin.Name, req.NodeLogin.Type, req.NodeLogin.Params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
_, err = models.SharedNodeLoginDAO.CreateNodeLogin(tx, nodeconfigs.NodeRoleDNS, req.NsNodeId, req.NodeLogin.Name, req.NodeLogin.Type, req.NodeLogin.Params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// InstallNSNode 安装节点
|
||||
func (this *NSNodeService) InstallNSNode(ctx context.Context, req *pb.InstallNSNodeRequest) (*pb.InstallNSNodeResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
goman.New(func() {
|
||||
err = installers.SharedNSNodeQueue().InstallNodeProcess(req.NsNodeId, false)
|
||||
if err != nil {
|
||||
logs.Println("[RPC]install dns node:" + err.Error())
|
||||
}
|
||||
})
|
||||
|
||||
return &pb.InstallNSNodeResponse{}, nil
|
||||
}
|
||||
|
||||
// FindNSNodeInstallStatus 读取节点安装状态
|
||||
func (this *NSNodeService) FindNSNodeInstallStatus(ctx context.Context, req *pb.FindNSNodeInstallStatusRequest) (*pb.FindNSNodeInstallStatusResponse, error) {
|
||||
// 校验请求
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
installStatus, err := models.SharedNSNodeDAO.FindNodeInstallStatus(tx, req.NsNodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if installStatus == nil {
|
||||
return &pb.FindNSNodeInstallStatusResponse{InstallStatus: nil}, nil
|
||||
}
|
||||
|
||||
pbInstallStatus := &pb.NodeInstallStatus{
|
||||
IsRunning: installStatus.IsRunning,
|
||||
IsFinished: installStatus.IsFinished,
|
||||
IsOk: installStatus.IsOk,
|
||||
Error: installStatus.Error,
|
||||
ErrorCode: installStatus.ErrorCode,
|
||||
UpdatedAt: installStatus.UpdatedAt,
|
||||
}
|
||||
return &pb.FindNSNodeInstallStatusResponse{InstallStatus: pbInstallStatus}, nil
|
||||
}
|
||||
|
||||
// UpdateNSNodeIsInstalled 修改节点安装状态
|
||||
func (this *NSNodeService) UpdateNSNodeIsInstalled(ctx context.Context, req *pb.UpdateNSNodeIsInstalledRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
err = models.SharedNSNodeDAO.UpdateNodeIsInstalled(tx, req.NsNodeId, req.IsInstalled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateNSNodeStatus 更新节点状态
|
||||
func (this *NSNodeService) UpdateNSNodeStatus(ctx context.Context, req *pb.UpdateNSNodeStatusRequest) (*pb.RPCSuccess, error) {
|
||||
// 校验节点
|
||||
_, nodeId, err := this.ValidateNodeId(ctx, rpcutils.UserTypeDNS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.NodeId > 0 {
|
||||
nodeId = req.NodeId
|
||||
}
|
||||
|
||||
if nodeId <= 0 {
|
||||
return nil, errors.New("'nodeId' should be greater than 0")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 修改时间戳
|
||||
var nodeStatus = &nodeconfigs.NodeStatus{}
|
||||
err = json.Unmarshal(req.StatusJSON, nodeStatus)
|
||||
if err != nil {
|
||||
return nil, errors.New("decode node status json failed: " + err.Error())
|
||||
}
|
||||
nodeStatus.UpdatedAt = time.Now().Unix()
|
||||
|
||||
// 保存
|
||||
err = models.SharedNSNodeDAO.UpdateNodeStatus(tx, nodeId, nodeStatus)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindCurrentNSNodeConfig 获取当前节点信息
|
||||
func (this *NSNodeService) FindCurrentNSNodeConfig(ctx context.Context, req *pb.FindCurrentNSNodeConfigRequest) (*pb.FindCurrentNSNodeConfigResponse, error) {
|
||||
// 校验节点
|
||||
_, nodeId, err := this.ValidateNodeId(ctx, rpcutils.UserTypeDNS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
config, err := models.SharedNSNodeDAO.ComposeNodeConfig(tx, nodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if config == nil {
|
||||
return &pb.FindCurrentNSNodeConfigResponse{NsNodeJSON: nil}, nil
|
||||
}
|
||||
configJSON, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.FindCurrentNSNodeConfigResponse{NsNodeJSON: configJSON}, nil
|
||||
}
|
||||
|
||||
// CheckNSNodeLatestVersion 检查新版本
|
||||
func (this *NSNodeService) CheckNSNodeLatestVersion(ctx context.Context, req *pb.CheckNSNodeLatestVersionRequest) (*pb.CheckNSNodeLatestVersionResponse, error) {
|
||||
_, _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin, rpcutils.UserTypeDNS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
deployFiles := installers.SharedDeployManager.LoadNSNodeFiles()
|
||||
for _, file := range deployFiles {
|
||||
if file.OS == req.Os && file.Arch == req.Arch && stringutil.VersionCompare(file.Version, req.CurrentVersion) > 0 {
|
||||
return &pb.CheckNSNodeLatestVersionResponse{
|
||||
HasNewVersion: true,
|
||||
NewVersion: file.Version,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
return &pb.CheckNSNodeLatestVersionResponse{HasNewVersion: false}, nil
|
||||
}
|
||||
|
||||
// FindLatestNSNodeVersion 获取NS节点最新版本
|
||||
func (this *NSNodeService) FindLatestNSNodeVersion(ctx context.Context, req *pb.FindLatestNSNodeVersionRequest) (*pb.FindLatestNSNodeVersionResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindLatestNSNodeVersionResponse{Version: teaconst.DNSNodeVersion}, nil
|
||||
}
|
||||
|
||||
// DownloadNSNodeInstallationFile 下载最新DNS节点安装文件
|
||||
func (this *NSNodeService) DownloadNSNodeInstallationFile(ctx context.Context, req *pb.DownloadNSNodeInstallationFileRequest) (*pb.DownloadNSNodeInstallationFileResponse, error) {
|
||||
nodeId, err := this.ValidateNSNode(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var file = installers.SharedDeployManager.FindNSNodeFile(req.Os, req.Arch)
|
||||
if file == nil {
|
||||
return &pb.DownloadNSNodeInstallationFileResponse{}, nil
|
||||
}
|
||||
|
||||
sum, err := file.Sum()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, offset, err := file.Read(req.ChunkOffset)
|
||||
if err != nil && err != io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 增加下载速度监控
|
||||
installers.SharedUpgradeLimiter.UpdateNodeBytes(nodeconfigs.NodeRoleDNS, nodeId, int64(len(data)))
|
||||
|
||||
return &pb.DownloadNSNodeInstallationFileResponse{
|
||||
Sum: sum,
|
||||
Offset: offset,
|
||||
ChunkData: data,
|
||||
Version: file.Version,
|
||||
Filename: filepath.Base(file.Path),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNSNodeConnectedAPINodes 更改节点连接的API节点信息
|
||||
func (this *NSNodeService) UpdateNSNodeConnectedAPINodes(ctx context.Context, req *pb.UpdateNSNodeConnectedAPINodesRequest) (*pb.RPCSuccess, error) {
|
||||
// 校验节点
|
||||
_, _, nodeId, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeDNS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
err = models.SharedNSNodeDAO.UpdateNodeConnectedAPINodes(tx, nodeId, req.ApiNodeIds)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateNSNodeLogin 修改节点登录信息
|
||||
func (this *NSNodeService) UpdateNSNodeLogin(ctx context.Context, req *pb.UpdateNSNodeLoginRequest) (*pb.RPCSuccess, error) {
|
||||
// 校验请求
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if req.NodeLogin.Id <= 0 {
|
||||
loginId, err := models.SharedNodeLoginDAO.CreateNodeLogin(tx, nodeconfigs.NodeRoleDNS, req.NsNodeId, req.NodeLogin.Name, req.NodeLogin.Type, req.NodeLogin.Params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
||||
// StartNSNode 启动节点
|
||||
func (this *NSNodeService) StartNSNode(ctx context.Context, req *pb.StartNSNodeRequest) (*pb.StartNSNodeResponse, error) {
|
||||
// 校验节点
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = installers.SharedNSNodeQueue().StartNode(req.NsNodeId)
|
||||
if err != nil {
|
||||
return &pb.StartNSNodeResponse{
|
||||
IsOk: false,
|
||||
Error: err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 修改状态
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedNSNodeDAO.UpdateNodeActive(tx, req.NsNodeId, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.StartNSNodeResponse{IsOk: true}, nil
|
||||
}
|
||||
|
||||
// StopNSNode 停止节点
|
||||
func (this *NSNodeService) StopNSNode(ctx context.Context, req *pb.StopNSNodeRequest) (*pb.StopNSNodeResponse, error) {
|
||||
// 校验节点
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = installers.SharedNSNodeQueue().StopNode(req.NsNodeId)
|
||||
if err != nil {
|
||||
return &pb.StopNSNodeResponse{
|
||||
IsOk: false,
|
||||
Error: err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 修改状态
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedNSNodeDAO.UpdateNodeActive(tx, req.NsNodeId, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.StopNSNodeResponse{IsOk: true}, nil
|
||||
}
|
||||
|
||||
// FindNSNodeDDoSProtection 获取集群的DDoS设置
|
||||
func (this *NSNodeService) FindNSNodeDDoSProtection(ctx context.Context, req *pb.FindNSNodeDDoSProtectionRequest) (*pb.FindNSNodeDDoSProtectionResponse, error) {
|
||||
var nodeId = req.NsNodeId
|
||||
var isFromNode = false
|
||||
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
// 检查是否来自节点
|
||||
currentNodeId, err2 := this.ValidateNSNode(ctx)
|
||||
if err2 != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if nodeId > 0 && currentNodeId != nodeId {
|
||||
return nil, errors.New("invalid 'nsNodeId'")
|
||||
}
|
||||
|
||||
nodeId = currentNodeId
|
||||
isFromNode = true
|
||||
}
|
||||
|
||||
var tx *dbs.Tx
|
||||
ddosProtection, err := models.SharedNSNodeDAO.FindNodeDDoSProtection(tx, nodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ddosProtection == nil {
|
||||
ddosProtection = ddosconfigs.DefaultProtectionConfig()
|
||||
}
|
||||
|
||||
// 组合父级节点配置
|
||||
// 只有从节点读取配置时才需要组合
|
||||
if isFromNode {
|
||||
clusterId, err := models.SharedNSNodeDAO.FindNodeClusterId(tx, nodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if clusterId > 0 {
|
||||
clusterDDoSProtection, err := models.SharedNSClusterDAO.FindClusterDDoSProtection(tx, clusterId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if clusterDDoSProtection == nil {
|
||||
clusterDDoSProtection = ddosconfigs.DefaultProtectionConfig()
|
||||
}
|
||||
|
||||
clusterDDoSProtection.Merge(ddosProtection)
|
||||
ddosProtection = clusterDDoSProtection
|
||||
}
|
||||
}
|
||||
|
||||
ddosProtectionJSON, err := json.Marshal(ddosProtection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result = &pb.FindNSNodeDDoSProtectionResponse{
|
||||
DdosProtectionJSON: ddosProtectionJSON,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UpdateNSNodeDDoSProtection 修改集群的DDoS设置
|
||||
func (this *NSNodeService) UpdateNSNodeDDoSProtection(ctx context.Context, req *pb.UpdateNSNodeDDoSProtectionRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ddosProtection = &ddosconfigs.ProtectionConfig{}
|
||||
err = json.Unmarshal(req.DdosProtectionJSON, ddosProtection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx *dbs.Tx
|
||||
err = models.SharedNSNodeDAO.UpdateNodeDDoSProtection(tx, req.NsNodeId, ddosProtection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSNodeAPIConfig 查找单个节点的API相关配置
|
||||
func (this *NSNodeService) FindNSNodeAPIConfig(ctx context.Context, req *pb.FindNSNodeAPIConfigRequest) (*pb.FindNSNodeAPIConfigResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
node, err := models.SharedNSNodeDAO.FindNodeAPIConfig(tx, req.NsNodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if node == nil {
|
||||
return &pb.FindNSNodeAPIConfigResponse{
|
||||
ApiNodeAddrsJSON: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &pb.FindNSNodeAPIConfigResponse{
|
||||
ApiNodeAddrsJSON: node.ApiNodeAddrs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNSNodeAPIConfig 修改某个节点的API相关配置
|
||||
func (this *NSNodeService) UpdateNSNodeAPIConfig(ctx context.Context, req *pb.UpdateNSNodeAPIConfigRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
var apiNodeAddrs = []*serverconfigs.NetworkAddressConfig{}
|
||||
if len(req.ApiNodeAddrsJSON) > 0 {
|
||||
err = json.Unmarshal(req.ApiNodeAddrsJSON, &apiNodeAddrs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedNSNodeDAO.UpdateNodeAPIConfig(tx, req.NsNodeId, apiNodeAddrs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
//go:build plus
|
||||
|
||||
package nameservers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CommandRequest 命令请求相关
|
||||
type CommandRequest struct {
|
||||
Id int64
|
||||
Code string
|
||||
CommandJSON []byte
|
||||
}
|
||||
|
||||
type CommandRequestWaiting struct {
|
||||
Timestamp int64
|
||||
Chan chan *pb.NSNodeStreamMessage
|
||||
}
|
||||
|
||||
func (this *CommandRequestWaiting) Close() {
|
||||
defer func() {
|
||||
_ = recover()
|
||||
}()
|
||||
|
||||
close(this.Chan)
|
||||
}
|
||||
|
||||
var responseChanMap = map[int64]*CommandRequestWaiting{} // request id => response
|
||||
var commandRequestId = int64(0)
|
||||
|
||||
var nodeLocker = &sync.Mutex{}
|
||||
var requestChanMap = map[int64]chan *CommandRequest{} // node id => chan
|
||||
|
||||
func NextCommandRequestId() int64 {
|
||||
return atomic.AddInt64(&commandRequestId, 1)
|
||||
}
|
||||
func init() {
|
||||
dbs.OnReadyDone(func() {
|
||||
// 清理WaitingChannelMap
|
||||
goman.New(func() {
|
||||
ticker := time.NewTicker(30 * time.Second)
|
||||
for range ticker.C {
|
||||
nodeLocker.Lock()
|
||||
for requestId, request := range responseChanMap {
|
||||
if time.Now().Unix()-request.Timestamp > 3600 {
|
||||
responseChanMap[requestId].Close()
|
||||
delete(responseChanMap, requestId)
|
||||
}
|
||||
}
|
||||
nodeLocker.Unlock()
|
||||
}
|
||||
})
|
||||
|
||||
// 自动同步连接到本API节点的NS节点任务
|
||||
goman.New(func() {
|
||||
defer func() {
|
||||
_ = recover()
|
||||
}()
|
||||
|
||||
// TODO 未来支持同步边缘节点
|
||||
var ticker = time.NewTicker(3 * time.Second)
|
||||
for range ticker.C {
|
||||
nodeIds, err := models.SharedNodeTaskDAO.FindAllDoingNodeIds(nil, nodeconfigs.NodeRoleDNS)
|
||||
if err != nil {
|
||||
remotelogs.Error("NSNodeService_SYNC", err.Error())
|
||||
continue
|
||||
}
|
||||
nodeLocker.Lock()
|
||||
for _, nodeId := range nodeIds {
|
||||
c, ok := requestChanMap[nodeId]
|
||||
if ok {
|
||||
select {
|
||||
case c <- &CommandRequest{
|
||||
Id: NextCommandRequestId(),
|
||||
Code: messageconfigs.NSMessageCodeNewNodeTask,
|
||||
CommandJSON: nil,
|
||||
}:
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
nodeLocker.Unlock()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// NsNodeStream 节点stream
|
||||
func (this *NSNodeService) NsNodeStream(server pb.NSNodeService_NsNodeStreamServer) error {
|
||||
// TODO 使用此stream快速通知NS节点更新
|
||||
// 校验节点
|
||||
_, _, nodeId, err := rpcutils.ValidateRequest(server.Context(), rpcutils.UserTypeDNS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 返回连接成功
|
||||
err = models.SharedNSNodeDAO.UpdateNodeConnectedAPINodes(nil, nodeId, []int64{teaconst.NodeId})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if Tea.IsTesting() {
|
||||
remotelogs.Println("NSNodeService", "accepted ns node '"+types.String(nodeId)+"' connection")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 是否发送恢复通知
|
||||
oldIsActive, err := models.SharedNSNodeDAO.FindNodeActive(tx, nodeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !oldIsActive {
|
||||
inactiveNotifiedAt, err := models.SharedNSNodeDAO.FindNodeInactiveNotifiedAt(tx, nodeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 设置为活跃
|
||||
err = models.SharedNSNodeDAO.UpdateNodeActive(tx, nodeId, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if inactiveNotifiedAt > 0 {
|
||||
// 发送恢复消息
|
||||
clusterId, err := models.SharedNSNodeDAO.FindNodeClusterId(tx, nodeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nodeName, err := models.SharedNSNodeDAO.FindEnabledNSNodeName(tx, nodeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
subject := "NS节点\"" + nodeName + "\"已经恢复在线"
|
||||
msg := "NS节点\"" + nodeName + "\"已经恢复在线"
|
||||
err = models.SharedMessageDAO.CreateNodeMessage(tx, nodeconfigs.NodeRoleDNS, clusterId, nodeId, models.MessageTypeNSNodeActive, models.MessageLevelSuccess, subject, msg, nil, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodeLocker.Lock()
|
||||
requestChan, ok := requestChanMap[nodeId]
|
||||
if !ok {
|
||||
requestChan = make(chan *CommandRequest, 1024)
|
||||
requestChanMap[nodeId] = requestChan
|
||||
}
|
||||
nodeLocker.Unlock()
|
||||
|
||||
defer func() {
|
||||
nodeLocker.Lock()
|
||||
delete(requestChanMap, nodeId)
|
||||
nodeLocker.Unlock()
|
||||
}()
|
||||
|
||||
// 发送请求
|
||||
goman.New(func() {
|
||||
for {
|
||||
select {
|
||||
case <-server.Context().Done():
|
||||
return
|
||||
case commandRequest := <-requestChan:
|
||||
// logs.Println("[RPC]sending command '" + commandRequest.Code + "' to node '" + strconv.FormatInt(nodeId, 10) + "'")
|
||||
retries := 3 // 错误重试次数
|
||||
for i := 0; i < retries; i++ {
|
||||
err := server.Send(&pb.NSNodeStreamMessage{
|
||||
RequestId: commandRequest.Id,
|
||||
Code: commandRequest.Code,
|
||||
DataJSON: commandRequest.CommandJSON,
|
||||
})
|
||||
if err != nil {
|
||||
if i == retries-1 {
|
||||
logs.Println("[RPC]send command '" + commandRequest.Code + "' failed: " + err.Error())
|
||||
} else {
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 接受请求
|
||||
for {
|
||||
req, err := server.Recv()
|
||||
if err != nil {
|
||||
// 修改节点状态
|
||||
err1 := models.SharedNSNodeDAO.UpdateNodeActive(tx, nodeId, false)
|
||||
if err1 != nil {
|
||||
logs.Println(err1.Error())
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func(req *pb.NSNodeStreamMessage) {
|
||||
// 因为 responseChan.Chan 有被关闭的风险,所以我们使用recover防止panic
|
||||
defer func() {
|
||||
_ = recover()
|
||||
}()
|
||||
|
||||
nodeLocker.Lock()
|
||||
responseChan, ok := responseChanMap[req.RequestId]
|
||||
if ok {
|
||||
select {
|
||||
case responseChan.Chan <- req:
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
nodeLocker.Unlock()
|
||||
}(req)
|
||||
}
|
||||
}
|
||||
|
||||
// SendCommandToNSNode 向节点发送命令
|
||||
func (this *NSNodeService) SendCommandToNSNode(ctx context.Context, req *pb.NSNodeStreamMessage) (*pb.NSNodeStreamMessage, error) {
|
||||
// 校验请求
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeId := req.NsNodeId
|
||||
if nodeId <= 0 {
|
||||
return nil, errors.New("node id should not be less than 0")
|
||||
}
|
||||
|
||||
nodeLocker.Lock()
|
||||
requestChan, ok := requestChanMap[nodeId]
|
||||
nodeLocker.Unlock()
|
||||
|
||||
if !ok {
|
||||
return &pb.NSNodeStreamMessage{
|
||||
RequestId: req.RequestId,
|
||||
IsOk: false,
|
||||
Message: "node '" + strconv.FormatInt(nodeId, 10) + "' not connected yet",
|
||||
}, nil
|
||||
}
|
||||
|
||||
req.RequestId = NextCommandRequestId()
|
||||
|
||||
select {
|
||||
case requestChan <- &CommandRequest{
|
||||
Id: req.RequestId,
|
||||
Code: req.Code,
|
||||
CommandJSON: req.DataJSON,
|
||||
}:
|
||||
// 加入到等待队列中
|
||||
respChan := make(chan *pb.NSNodeStreamMessage, 1)
|
||||
waiting := &CommandRequestWaiting{
|
||||
Timestamp: time.Now().Unix(),
|
||||
Chan: respChan,
|
||||
}
|
||||
|
||||
nodeLocker.Lock()
|
||||
responseChanMap[req.RequestId] = waiting
|
||||
nodeLocker.Unlock()
|
||||
|
||||
// 等待响应
|
||||
timeoutSeconds := req.TimeoutSeconds
|
||||
if timeoutSeconds <= 0 {
|
||||
timeoutSeconds = 10
|
||||
}
|
||||
timeout := time.NewTimer(time.Duration(timeoutSeconds) * time.Second)
|
||||
select {
|
||||
case resp := <-respChan:
|
||||
// 从队列中删除
|
||||
nodeLocker.Lock()
|
||||
delete(responseChanMap, req.RequestId)
|
||||
waiting.Close()
|
||||
nodeLocker.Unlock()
|
||||
|
||||
if resp == nil {
|
||||
return &pb.NSNodeStreamMessage{
|
||||
RequestId: req.RequestId,
|
||||
Code: req.Code,
|
||||
Message: "response timeout",
|
||||
IsOk: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
case <-timeout.C:
|
||||
// 从队列中删除
|
||||
nodeLocker.Lock()
|
||||
delete(responseChanMap, req.RequestId)
|
||||
waiting.Close()
|
||||
nodeLocker.Unlock()
|
||||
|
||||
return &pb.NSNodeStreamMessage{
|
||||
RequestId: req.RequestId,
|
||||
Code: req.Code,
|
||||
Message: "response timeout over " + fmt.Sprintf("%d", timeoutSeconds) + " seconds",
|
||||
IsOk: false,
|
||||
}, nil
|
||||
}
|
||||
default:
|
||||
return &pb.NSNodeStreamMessage{
|
||||
RequestId: req.RequestId,
|
||||
Code: req.Code,
|
||||
Message: "command queue is full over " + strconv.Itoa(len(requestChan)),
|
||||
IsOk: false,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
191
EdgeAPI/internal/rpc/services/nameservers/service_ns_plan.go
Normal file
191
EdgeAPI/internal/rpc/services/nameservers/service_ns_plan.go
Normal file
@@ -0,0 +1,191 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build plus
|
||||
|
||||
package nameservers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
// NSPlanService DNS套餐服务
|
||||
type NSPlanService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateNSPlan 创建DNS套餐
|
||||
func (this *NSPlanService) CreateNSPlan(ctx context.Context, req *pb.CreateNSPlanRequest) (*pb.CreateNSPlanResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if len(req.ConfigJSON) == 0 {
|
||||
return nil, errors.New("invalid 'configJSON'")
|
||||
}
|
||||
|
||||
var config = dnsconfigs.DefaultNSPlanConfig()
|
||||
err = json.Unmarshal(req.ConfigJSON, config)
|
||||
if err != nil {
|
||||
return nil, errors.New("decode 'configJSON' failed: " + err.Error())
|
||||
}
|
||||
|
||||
planId, err := nameservers.SharedNSPlanDAO.CreatePlan(tx, req.Name, req.MonthlyPrice, req.YearlyPrice, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CreateNSPlanResponse{NsPlanId: planId}, nil
|
||||
}
|
||||
|
||||
// UpdateNSPlan 修改DNS套餐
|
||||
func (this *NSPlanService) UpdateNSPlan(ctx context.Context, req *pb.UpdateNSPlanRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if len(req.ConfigJSON) == 0 {
|
||||
return nil, errors.New("invalid 'configJSON'")
|
||||
}
|
||||
|
||||
var config = dnsconfigs.DefaultNSPlanConfig()
|
||||
err = json.Unmarshal(req.ConfigJSON, config)
|
||||
if err != nil {
|
||||
return nil, errors.New("decode 'configJSON' failed: " + err.Error())
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSPlanDAO.UpdatePlan(tx, req.NsPlanId, req.Name, req.IsOn, req.MonthlyPrice, req.YearlyPrice, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// SortNSPlanOrders 修改DNS套餐顺序
|
||||
func (this *NSPlanService) SortNSPlanOrders(ctx context.Context, req *pb.SortNSPlansRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = nameservers.SharedNSPlanDAO.UpdatePlanOrders(tx, req.NsPlanIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindAllNSPlans 查找所有DNS套餐
|
||||
func (this *NSPlanService) FindAllNSPlans(ctx context.Context, req *pb.FindAllNSPlansRequest) (*pb.FindAllNSPlansResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
var pbPlans = []*pb.NSPlan{}
|
||||
plans, err := nameservers.SharedNSPlanDAO.FindAllPlans(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, plan := range plans {
|
||||
pbPlans = append(pbPlans, &pb.NSPlan{
|
||||
Id: int64(plan.Id),
|
||||
Name: plan.Name,
|
||||
IsOn: plan.IsOn,
|
||||
MonthlyPrice: float32(plan.MonthlyPrice),
|
||||
YearlyPrice: float32(plan.YearlyPrice),
|
||||
ConfigJSON: plan.Config,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FindAllNSPlansResponse{NsPlans: pbPlans}, nil
|
||||
}
|
||||
|
||||
// FindAllEnabledNSPlans 查找所有可用DNS套餐
|
||||
func (this *NSPlanService) FindAllEnabledNSPlans(ctx context.Context, req *pb.FindAllEnabledNSPlansRequest) (*pb.FindAllEnabledNSPlansResponse, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
var pbPlans = []*pb.NSPlan{}
|
||||
plans, err := nameservers.SharedNSPlanDAO.FindAllEnabledPlans(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, plan := range plans {
|
||||
pbPlans = append(pbPlans, &pb.NSPlan{
|
||||
Id: int64(plan.Id),
|
||||
Name: plan.Name,
|
||||
IsOn: plan.IsOn,
|
||||
MonthlyPrice: float32(plan.MonthlyPrice),
|
||||
YearlyPrice: float32(plan.YearlyPrice),
|
||||
ConfigJSON: plan.Config,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FindAllEnabledNSPlansResponse{NsPlans: pbPlans}, nil
|
||||
}
|
||||
|
||||
// FindNSPlan 查找DNS套餐
|
||||
func (this *NSPlanService) FindNSPlan(ctx context.Context, req *pb.FindNSPlanRequest) (*pb.FindNSPlanResponse, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
plan, err := nameservers.SharedNSPlanDAO.FindEnabledNSPlan(tx, req.NsPlanId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if plan == nil {
|
||||
return &pb.FindNSPlanResponse{}, nil
|
||||
}
|
||||
|
||||
return &pb.FindNSPlanResponse{
|
||||
NsPlan: &pb.NSPlan{
|
||||
Id: int64(plan.Id),
|
||||
Name: plan.Name,
|
||||
IsOn: plan.IsOn,
|
||||
MonthlyPrice: float32(plan.MonthlyPrice),
|
||||
YearlyPrice: float32(plan.YearlyPrice),
|
||||
ConfigJSON: plan.Config,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteNSPlan 删除DNS套餐
|
||||
func (this *NSPlanService) DeleteNSPlan(ctx context.Context, req *pb.DeleteNSPlanRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
err = nameservers.SharedNSPlanDAO.DisableNSPlan(tx, req.NsPlanId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build plus
|
||||
|
||||
package nameservers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
// NSQuestionOptionService DNS查询选项
|
||||
type NSQuestionOptionService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateNSQuestionOption 创建选项
|
||||
func (this *NSQuestionOptionService) CreateNSQuestionOption(ctx context.Context, req *pb.CreateNSQuestionOptionRequest) (*pb.CreateNSQuestionOptionResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
var values = maps.Map{}
|
||||
if len(req.ValuesJSON) > 0 {
|
||||
err = json.Unmarshal(req.ValuesJSON, &values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
optionId, err := nameservers.SharedNSQuestionOptionDAO.CreateOption(tx, req.Name, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.CreateNSQuestionOptionResponse{NsQuestionOptionId: optionId}, nil
|
||||
}
|
||||
|
||||
// FindNSQuestionOption 读取选项
|
||||
func (this *NSQuestionOptionService) FindNSQuestionOption(ctx context.Context, req *pb.FindNSQuestionOptionRequest) (*pb.FindNSQuestionOptionResponse, error) {
|
||||
_, err := this.ValidateNSNode(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
option, err := nameservers.SharedNSQuestionOptionDAO.FindOption(tx, req.NsQuestionOptionId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if option == nil {
|
||||
return &pb.FindNSQuestionOptionResponse{NsQuestionOption: nil}, nil
|
||||
}
|
||||
|
||||
return &pb.FindNSQuestionOptionResponse{NsQuestionOption: &pb.NSQuestionOption{
|
||||
Id: int64(option.Id),
|
||||
Name: option.Name,
|
||||
ValuesJSON: option.Values,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
// DeleteNSQuestionOption 删除选项
|
||||
func (this *NSQuestionOptionService) DeleteNSQuestionOption(ctx context.Context, req *pb.DeleteNSQuestionOptionRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = nameservers.SharedNSQuestionOptionDAO.DeleteOption(tx, req.NsQuestionOptionId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
993
EdgeAPI/internal/rpc/services/nameservers/service_ns_record.go
Normal file
993
EdgeAPI/internal/rpc/services/nameservers/service_ns_record.go
Normal file
@@ -0,0 +1,993 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build plus
|
||||
|
||||
package nameservers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
|
||||
"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/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NSRecordService 域名记录相关服务
|
||||
type NSRecordService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateNSRecord 创建记录
|
||||
func (this *NSRecordService) CreateNSRecord(ctx context.Context, req *pb.CreateNSRecordRequest) (*pb.CreateNSRecordResponse, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainDAO.CheckUserDomain(tx, userId, req.NsDomainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// 检查线路代号
|
||||
if len(req.NsRouteCodes) > 0 {
|
||||
err = nameservers.SharedNSRouteDAO.CheckRouteCodes(tx, req.NsRouteCodes, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
recordId, err := nameservers.SharedNSRecordDAO.CreateRecord(tx, req.NsDomainId, req.Description, req.Name, req.Type, req.Value, req.MxPriority, req.SrvPriority, req.SrvWeight, req.SrvPort, req.CaaFlag, req.CaaTag, req.Ttl, req.NsRouteCodes, req.Weight)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.CreateNSRecordResponse{NsRecordId: recordId}, nil
|
||||
}
|
||||
|
||||
// CreateNSRecords 创建记录
|
||||
func (this *NSRecordService) CreateNSRecords(ctx context.Context, req *pb.CreateNSRecordsRequest) (*pb.CreateNSRecordsResponse, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainDAO.CheckUserDomain(tx, userId, req.NsDomainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var recordIds = []int64{}
|
||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||
for _, name := range req.Names {
|
||||
// 检查线路代号
|
||||
if len(req.NsRouteCodes) > 0 {
|
||||
err = nameservers.SharedNSRouteDAO.CheckRouteCodes(tx, req.NsRouteCodes, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
recordId, err := nameservers.SharedNSRecordDAO.CreateRecord(tx, req.NsDomainId, req.Description, name, req.Type, req.Value, req.MxPriority, req.SrvPriority, req.SrvWeight, req.SrvPort, req.CaaFlag, req.CaaTag, req.Ttl, req.NsRouteCodes, req.Weight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recordIds = append(recordIds, recordId)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CreateNSRecordsResponse{NsRecordIds: recordIds}, nil
|
||||
}
|
||||
|
||||
// CreateNSRecordsWithDomainNames 为一组域名批量创建记录
|
||||
func (this *NSRecordService) CreateNSRecordsWithDomainNames(ctx context.Context, req *pb.CreateNSRecordsWithDomainNamesRequest) (*pb.RPCSuccess, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
if len(req.RecordsJSON) == 0 {
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
type recordItem struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
MxPriority int32 `json:"mxPriority"`
|
||||
|
||||
SRVPriority int32 `json:"srvPriority"`
|
||||
SRVWeight int32 `json:"srvWeight"`
|
||||
SRVPort int32 `json:"srvPort"`
|
||||
|
||||
CAAFlag int32 `json:"caaFlag"`
|
||||
CAATag string `json:"caaTag"`
|
||||
|
||||
RouteCodes []string `json:"routeCodes"`
|
||||
TTL int32 `json:"ttl"`
|
||||
Weight int32 `json:"weight"`
|
||||
}
|
||||
|
||||
var records = []*recordItem{}
|
||||
err = json.Unmarshal(req.RecordsJSON, &records)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(records) == 0 {
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||
for _, domainName := range req.NsDomainNames {
|
||||
domainName = strings.ToLower(strings.TrimSpace(domainName))
|
||||
if len(domainName) == 0 {
|
||||
continue
|
||||
}
|
||||
domainId, err := nameservers.SharedNSDomainDAO.FindDomainIdWithName(tx, 0, req.UserId, domainName, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if domainId <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 是否删除所有以往记录
|
||||
if req.RemoveAll {
|
||||
err = nameservers.SharedNSRecordDAO.DisableRecordsInDomain(tx, domainId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, record := range records {
|
||||
record.Type = strings.ToLower(record.Type)
|
||||
|
||||
if !req.RemoveAll && req.RemoveOld {
|
||||
err = nameservers.SharedNSRecordDAO.DisableRecordsInDomainWithNameAndType(tx, domainId, record.Name, record.Type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 检查线路代号
|
||||
if len(record.RouteCodes) > 0 {
|
||||
err = nameservers.SharedNSRouteDAO.CheckRouteCodes(tx, record.RouteCodes, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = nameservers.SharedNSRecordDAO.CreateRecord(tx, domainId, "批量创建", record.Name, strings.ToUpper(record.Type), record.Value, record.MxPriority, record.SRVPriority, record.SRVWeight, record.SRVPort, record.CAAFlag, record.CAATag, record.TTL, record.RouteCodes, record.Weight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateNSRecordsWithDomainNames 批量修改一组域名的一组记录
|
||||
func (this *NSRecordService) UpdateNSRecordsWithDomainNames(ctx context.Context, req *pb.UpdateNSRecordsWithDomainNamesRequest) (*pb.RPCSuccess, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||
for _, domainName := range req.NsDomainNames {
|
||||
domainName = strings.ToLower(strings.TrimSpace(domainName))
|
||||
if len(domainName) == 0 {
|
||||
continue
|
||||
}
|
||||
domainId, err := nameservers.SharedNSDomainDAO.FindDomainIdWithName(tx, 0, req.UserId, domainName, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if domainId <= 0 {
|
||||
continue
|
||||
}
|
||||
err = nameservers.SharedNSRecordDAO.UpdateRecordsWithDomainId(tx, domainId, req.SearchName, req.SearchType, req.SearchValue, req.SearchNSRouteCodes, req.NewName, req.NewType, req.NewValue, req.NewNSRouteCodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// DeleteNSRecordsWithDomainNames 批量删除一组域名的一组记录
|
||||
func (this *NSRecordService) DeleteNSRecordsWithDomainNames(ctx context.Context, req *pb.DeleteNSRecordsWithDomainNamesRequest) (*pb.RPCSuccess, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||
for _, domainName := range req.NsDomainNames {
|
||||
domainName = strings.ToLower(strings.TrimSpace(domainName))
|
||||
if len(domainName) == 0 {
|
||||
continue
|
||||
}
|
||||
domainId, err := nameservers.SharedNSDomainDAO.FindDomainIdWithName(tx, 0, req.UserId, domainName, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if domainId <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSRecordDAO.DisableRecordsWithDomainId(tx, domainId, req.SearchName, req.SearchType, req.SearchValue, req.SearchNSRouteCodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateNSRecordsIsOnWithDomainNames 批量一组域名的一组记录启用状态
|
||||
func (this *NSRecordService) UpdateNSRecordsIsOnWithDomainNames(ctx context.Context, req *pb.UpdateNSRecordsIsOnWithDomainNamesRequest) (*pb.RPCSuccess, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||
for _, domainName := range req.NsDomainNames {
|
||||
domainName = strings.ToLower(strings.TrimSpace(domainName))
|
||||
if len(domainName) == 0 {
|
||||
continue
|
||||
}
|
||||
domainId, err := nameservers.SharedNSDomainDAO.FindDomainIdWithName(tx, 0, req.UserId, domainName, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if domainId <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSRecordDAO.UpdateRecordsIsOnWithDomainId(tx, domainId, req.SearchName, req.SearchType, req.SearchValue, req.SearchNSRouteCodes, req.IsOn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// ImportNSRecords 导入域名解析
|
||||
func (this *NSRecordService) ImportNSRecords(ctx context.Context, req *pb.ImportNSRecordsRequest) (*pb.RPCSuccess, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||
for _, record := range req.NsRecords {
|
||||
var domainName = strings.ToLower(strings.TrimSpace(record.NsDomainName))
|
||||
if len(domainName) == 0 {
|
||||
continue
|
||||
}
|
||||
domainId, err := nameservers.SharedNSDomainDAO.FindDomainIdWithName(tx, 0, req.UserId, domainName, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if domainId <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if record.Ttl <= 0 {
|
||||
record.Ttl = 600
|
||||
}
|
||||
|
||||
_, err = nameservers.SharedNSRecordDAO.CreateRecord(tx, domainId, "批量导入", record.Name, record.Type, record.Value, record.MxPriority, record.SrvPriority, record.SrvWeight, record.SrvPort, record.CaaFlag, record.CaaTag, record.Ttl, nil, record.Weight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateNSRecord 修改记录
|
||||
func (this *NSRecordService) UpdateNSRecord(ctx context.Context, req *pb.UpdateNSRecordRequest) (*pb.RPCSuccess, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSRecordDAO.CheckUserRecord(tx, userId, req.NsRecordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSRecordDAO.UpdateRecord(tx, req.NsRecordId, req.Description, req.Name, req.Type, req.Value, req.MxPriority, req.SrvPriority, req.SrvWeight, req.SrvPort, req.CaaFlag, req.CaaTag, req.Ttl, req.NsRouteCodes, req.Weight, req.IsOn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// DeleteNSRecord 删除记录
|
||||
func (this *NSRecordService) DeleteNSRecord(ctx context.Context, req *pb.DeleteNSRecordRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSRecordDAO.CheckUserRecord(tx, userId, req.NsRecordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSRecordDAO.DisableNSRecord(tx, req.NsRecordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// CountAllNSRecords 计算记录数量
|
||||
func (this *NSRecordService) CountAllNSRecords(ctx context.Context, req *pb.CountAllNSRecordsRequest) (*pb.RPCCountResponse, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainDAO.CheckUserDomain(tx, userId, req.NsDomainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
count, err := nameservers.SharedNSRecordDAO.CountAllEnabledDomainRecords(tx, req.NsDomainId, req.Type, req.Keyword, req.NsRouteCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.SuccessCount(count)
|
||||
}
|
||||
|
||||
// CountAllNSRecordsWithName 查询相同记录名的记录数
|
||||
func (this *NSRecordService) CountAllNSRecordsWithName(ctx context.Context, req *pb.CountAllNSRecordsWithNameRequest) (*pb.RPCCountResponse, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainDAO.CheckUserDomain(tx, userId, req.NsDomainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
count, err := nameservers.SharedNSRecordDAO.CountAllRecordsWithName(tx, req.NsDomainId, req.Type, req.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.SuccessCount(count)
|
||||
}
|
||||
|
||||
// ListNSRecords 读取单页记录
|
||||
func (this *NSRecordService) ListNSRecords(ctx context.Context, req *pb.ListNSRecordsRequest) (*pb.ListNSRecordsResponse, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainDAO.CheckUserDomain(tx, userId, req.NsDomainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
records, err := nameservers.SharedNSRecordDAO.ListEnabledRecords(tx, req.NsDomainId, req.Type, req.Keyword, req.NsRouteCode, req.NameAsc, req.NameDesc, req.TypeAsc, req.TypeDesc, req.TtlAsc, req.TtlDesc, req.UpAsc, req.UpDesc, req.Offset, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbRecords = []*pb.NSRecord{}
|
||||
for _, record := range records {
|
||||
// 线路
|
||||
var pbRoutes = []*pb.NSRoute{}
|
||||
for _, routeCode := range record.DecodeRouteIds() {
|
||||
route, err := nameservers.SharedNSRouteDAO.FindEnabledRouteWithCode(tx, routeCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if route == nil {
|
||||
continue
|
||||
}
|
||||
pbRoutes = append(pbRoutes, &pb.NSRoute{
|
||||
Id: int64(route.Id),
|
||||
Name: route.Name,
|
||||
Code: route.Code,
|
||||
})
|
||||
|
||||
// TODO 读取其他线路
|
||||
}
|
||||
|
||||
pbRecords = append(pbRecords, &pb.NSRecord{
|
||||
Id: int64(record.Id),
|
||||
Description: record.Description,
|
||||
Name: record.Name,
|
||||
Type: record.Type,
|
||||
Value: record.Value,
|
||||
MxPriority: int32(record.MxPriority),
|
||||
Ttl: types.Int32(record.Ttl),
|
||||
Weight: types.Int32(record.Weight),
|
||||
CreatedAt: int64(record.CreatedAt),
|
||||
IsOn: record.IsOn,
|
||||
NsDomain: nil,
|
||||
NsRoutes: pbRoutes,
|
||||
HealthCheckJSON: record.HealthCheck,
|
||||
IsUp: record.IsUp,
|
||||
})
|
||||
}
|
||||
return &pb.ListNSRecordsResponse{NsRecords: pbRecords}, nil
|
||||
}
|
||||
|
||||
// FindNSRecord 查询单个记录信息
|
||||
func (this *NSRecordService) FindNSRecord(ctx context.Context, req *pb.FindNSRecordRequest) (*pb.FindNSRecordResponse, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSRecordDAO.CheckUserRecord(tx, userId, req.NsRecordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
record, err := nameservers.SharedNSRecordDAO.FindEnabledNSRecord(tx, req.NsRecordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if record == nil {
|
||||
return &pb.FindNSRecordResponse{NsRecord: nil}, nil
|
||||
}
|
||||
|
||||
// 域名
|
||||
domain, err := nameservers.SharedNSDomainDAO.FindEnabledNSDomain(tx, int64(record.DomainId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if domain == nil {
|
||||
return &pb.FindNSRecordResponse{NsRecord: nil}, nil
|
||||
}
|
||||
var pbDomain = &pb.NSDomain{
|
||||
Id: int64(domain.Id),
|
||||
Name: domain.Name,
|
||||
IsOn: domain.IsOn,
|
||||
}
|
||||
|
||||
// 线路
|
||||
var pbRoutes = []*pb.NSRoute{}
|
||||
for _, routeCode := range record.DecodeRouteIds() {
|
||||
route, err := nameservers.SharedNSRouteDAO.FindEnabledRouteWithCode(tx, routeCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if route == nil {
|
||||
continue
|
||||
}
|
||||
pbRoutes = append(pbRoutes, &pb.NSRoute{
|
||||
Id: int64(route.Id),
|
||||
Name: route.Name,
|
||||
Code: route.Code,
|
||||
})
|
||||
}
|
||||
|
||||
// TODO 读取其他线路
|
||||
|
||||
return &pb.FindNSRecordResponse{NsRecord: &pb.NSRecord{
|
||||
Id: int64(record.Id),
|
||||
Description: record.Description,
|
||||
Name: record.Name,
|
||||
Type: record.Type,
|
||||
Value: record.Value,
|
||||
MxPriority: types.Int32(record.MxPriority),
|
||||
SrvPort: types.Int32(record.SrvPort),
|
||||
SrvPriority: types.Int32(record.SrvPriority),
|
||||
SrvWeight: types.Int32(record.SrvWeight),
|
||||
CaaFlag: types.Int32(record.CaaFlag),
|
||||
CaaTag: record.CaaTag,
|
||||
Ttl: types.Int32(record.Ttl),
|
||||
Weight: types.Int32(record.Weight),
|
||||
CreatedAt: int64(record.CreatedAt),
|
||||
IsOn: record.IsOn,
|
||||
NsDomain: pbDomain,
|
||||
NsRoutes: pbRoutes,
|
||||
HealthCheckJSON: record.HealthCheck,
|
||||
IsUp: record.IsUp,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
// FindNSRecordWithNameAndType 使用名称和类型查询单个记录信息
|
||||
func (this *NSRecordService) FindNSRecordWithNameAndType(ctx context.Context, req *pb.FindNSRecordWithNameAndTypeRequest) (*pb.FindNSRecordWithNameAndTypeResponse, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
if req.NsDomainId <= 0 {
|
||||
return &pb.FindNSRecordWithNameAndTypeResponse{
|
||||
NsRecord: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainDAO.CheckUserDomain(tx, userId, req.NsDomainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
record, err := nameservers.SharedNSRecordDAO.FindEnabledRecordWithName(tx, req.NsDomainId, req.Name, req.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if record == nil {
|
||||
return &pb.FindNSRecordWithNameAndTypeResponse{
|
||||
NsRecord: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 线路
|
||||
var pbRoutes = []*pb.NSRoute{}
|
||||
for _, routeCode := range record.DecodeRouteIds() {
|
||||
route, err := nameservers.SharedNSRouteDAO.FindEnabledRouteWithCode(tx, routeCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if route == nil {
|
||||
continue
|
||||
}
|
||||
pbRoutes = append(pbRoutes, &pb.NSRoute{
|
||||
Id: int64(route.Id),
|
||||
Name: route.Name,
|
||||
Code: route.Code,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FindNSRecordWithNameAndTypeResponse{
|
||||
NsRecord: &pb.NSRecord{
|
||||
Id: int64(record.Id),
|
||||
Description: record.Description,
|
||||
Name: record.Name,
|
||||
Type: record.Type,
|
||||
Value: record.Value,
|
||||
MxPriority: types.Int32(record.MxPriority),
|
||||
SrvPriority: types.Int32(record.SrvPriority),
|
||||
SrvWeight: types.Int32(record.SrvWeight),
|
||||
SrvPort: types.Int32(record.SrvPort),
|
||||
CaaFlag: types.Int32(record.CaaFlag),
|
||||
CaaTag: record.CaaTag,
|
||||
Ttl: types.Int32(record.Ttl),
|
||||
Weight: types.Int32(record.Weight),
|
||||
CreatedAt: int64(record.CreatedAt),
|
||||
IsOn: record.IsOn,
|
||||
NsRoutes: pbRoutes,
|
||||
HealthCheckJSON: record.HealthCheck,
|
||||
IsUp: record.IsUp,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindNSRecordsWithNameAndType 使用名称和类型查询多个记录信息
|
||||
func (this *NSRecordService) FindNSRecordsWithNameAndType(ctx context.Context, req *pb.FindNSRecordsWithNameAndTypeRequest) (*pb.FindNSRecordsWithNameAndTypeResponse, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
if req.NsDomainId <= 0 {
|
||||
return &pb.FindNSRecordsWithNameAndTypeResponse{
|
||||
NsRecords: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSDomainDAO.CheckUserDomain(tx, userId, req.NsDomainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
records, err := nameservers.SharedNSRecordDAO.FindEnabledRecordsWithName(tx, req.NsDomainId, req.Name, req.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pbRecords = []*pb.NSRecord{}
|
||||
|
||||
for _, record := range records {
|
||||
// 线路
|
||||
var pbRoutes = []*pb.NSRoute{}
|
||||
for _, routeCode := range record.DecodeRouteIds() {
|
||||
route, err := nameservers.SharedNSRouteDAO.FindEnabledRouteWithCode(tx, routeCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if route == nil {
|
||||
continue
|
||||
}
|
||||
pbRoutes = append(pbRoutes, &pb.NSRoute{
|
||||
Id: int64(route.Id),
|
||||
Name: route.Name,
|
||||
Code: route.Code,
|
||||
})
|
||||
}
|
||||
|
||||
pbRecords = append(pbRecords, &pb.NSRecord{
|
||||
Id: int64(record.Id),
|
||||
Description: record.Description,
|
||||
Name: record.Name,
|
||||
Type: record.Type,
|
||||
Value: record.Value,
|
||||
MxPriority: int32(record.MxPriority),
|
||||
SrvPriority: types.Int32(record.SrvPriority),
|
||||
SrvWeight: types.Int32(record.SrvWeight),
|
||||
SrvPort: types.Int32(record.SrvPort),
|
||||
CaaFlag: types.Int32(record.CaaFlag),
|
||||
CaaTag: record.CaaTag,
|
||||
Ttl: types.Int32(record.Ttl),
|
||||
Weight: types.Int32(record.Weight),
|
||||
CreatedAt: int64(record.CreatedAt),
|
||||
IsOn: record.IsOn,
|
||||
NsRoutes: pbRoutes,
|
||||
HealthCheckJSON: record.HealthCheck,
|
||||
IsUp: record.IsUp,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FindNSRecordsWithNameAndTypeResponse{
|
||||
NsRecords: pbRecords,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListNSRecordsAfterVersion 根据版本列出一组记录
|
||||
func (this *NSRecordService) ListNSRecordsAfterVersion(ctx context.Context, req *pb.ListNSRecordsAfterVersionRequest) (*pb.ListNSRecordsAfterVersionResponse, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, _, err := this.ValidateNodeId(ctx, rpcutils.UserTypeDNS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return &pb.ListNSRecordsAfterVersionResponse{
|
||||
NsRecords: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 集群ID
|
||||
var tx = this.NullTx()
|
||||
if req.Size <= 0 {
|
||||
req.Size = 2000
|
||||
}
|
||||
records, err := nameservers.SharedNSRecordDAO.ListRecordsAfterVersion(tx, req.Version, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pbRecords []*pb.NSRecord
|
||||
for _, record := range records {
|
||||
// 线路
|
||||
pbRoutes := []*pb.NSRoute{}
|
||||
routeIds := record.DecodeRouteIds()
|
||||
for _, routeId := range routeIds {
|
||||
var routeIdInt int64 = 0
|
||||
if regexp.MustCompile(`^id:\d+$`).MatchString(routeId) {
|
||||
routeIdInt = types.Int64(routeId[strings.Index(routeId, ":")+1:])
|
||||
}
|
||||
|
||||
pbRoutes = append(pbRoutes, &pb.NSRoute{
|
||||
Id: routeIdInt,
|
||||
Code: routeId,
|
||||
})
|
||||
}
|
||||
|
||||
// TODO 读取其他线路
|
||||
|
||||
pbRecords = append(pbRecords, &pb.NSRecord{
|
||||
Id: int64(record.Id),
|
||||
Description: "",
|
||||
Name: record.Name,
|
||||
Type: record.Type,
|
||||
Value: record.Value,
|
||||
MxPriority: int32(record.MxPriority),
|
||||
SrvPriority: types.Int32(record.SrvPriority),
|
||||
SrvWeight: types.Int32(record.SrvWeight),
|
||||
SrvPort: types.Int32(record.SrvPort),
|
||||
CaaFlag: types.Int32(record.CaaFlag),
|
||||
CaaTag: record.CaaTag,
|
||||
Ttl: types.Int32(record.Ttl),
|
||||
Weight: types.Int32(record.Weight),
|
||||
IsDeleted: record.State == nameservers.NSRecordStateDisabled,
|
||||
IsOn: record.IsOn && record.IsUp,
|
||||
Version: int64(record.Version),
|
||||
NsDomain: &pb.NSDomain{Id: int64(record.DomainId)},
|
||||
NsRoutes: pbRoutes,
|
||||
HealthCheckJSON: record.HealthCheck,
|
||||
IsUp: record.IsUp,
|
||||
})
|
||||
}
|
||||
return &pb.ListNSRecordsAfterVersionResponse{NsRecords: pbRecords}, nil
|
||||
}
|
||||
|
||||
// FindNSRecordHealthCheck 查询记录健康检查设置
|
||||
func (this *NSRecordService) FindNSRecordHealthCheck(ctx context.Context, req *pb.FindNSRecordHealthCheckRequest) (*pb.FindNSRecordHealthCheckResponse, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSRecordDAO.CheckUserRecord(tx, userId, req.NsRecordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO 检查套餐
|
||||
}
|
||||
|
||||
config, err := nameservers.SharedNSRecordDAO.FindRecordHealthCheckConfig(tx, req.NsRecordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configJSON, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindNSRecordHealthCheckResponse{NsRecordHealthCheckJSON: configJSON}, nil
|
||||
}
|
||||
|
||||
// UpdateNSRecordHealthCheck 修改记录健康检查设置
|
||||
func (this *NSRecordService) UpdateNSRecordHealthCheck(ctx context.Context, req *pb.UpdateNSRecordHealthCheckRequest) (*pb.RPCSuccess, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSRecordDAO.CheckUserRecord(tx, userId, req.NsRecordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO 检查套餐
|
||||
}
|
||||
|
||||
if len(req.NsRecordHealthCheckJSON) == 0 {
|
||||
return nil, errors.New("invalid 'nsRecordHealthCheckJSON'")
|
||||
}
|
||||
var healthCheckConfig = dnsconfigs.NewNSRecordHealthCheckConfig()
|
||||
err = json.Unmarshal(req.NsRecordHealthCheckJSON, healthCheckConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("decode 'nsRecordHealthCheckJSON' failed: " + err.Error())
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSRecordDAO.UpdateRecordHealthCheckConfig(tx, req.NsRecordId, healthCheckConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateNSRecordIsUp 手动修改记录在线状态
|
||||
func (this *NSRecordService) UpdateNSRecordIsUp(ctx context.Context, req *pb.UpdateNSRecordIsUpRequest) (*pb.RPCSuccess, error) {
|
||||
// 检查是否为商业用户
|
||||
if !teaconst.IsPlus {
|
||||
return nil, errors.New("non commercial user")
|
||||
}
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSRecordDAO.CheckUserRecord(tx, userId, req.NsRecordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO 检查套餐
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSRecordDAO.UpdateRecordIsUp(tx, req.NsRecordId, req.IsUp, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
// 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/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/rpc/pb"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NSRecordHourlyStatService NS记录小时统计
|
||||
type NSRecordHourlyStatService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// UploadNSRecordHourlyStats 上传统计
|
||||
func (this *NSRecordHourlyStatService) UploadNSRecordHourlyStats(ctx context.Context, req *pb.UploadNSRecordHourlyStatsRequest) (*pb.RPCSuccess, error) {
|
||||
_, nodeId, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeDNS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if nodeId <= 0 {
|
||||
return nil, errors.New("invalid nodeId")
|
||||
}
|
||||
if len(req.Stats) == 0 {
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
clusterId, err := models.SharedNSNodeDAO.FindNodeClusterId(tx, nodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 增加小时统计
|
||||
for _, stat := range req.Stats {
|
||||
err := nameservers.SharedNSRecordHourlyStatDAO.IncreaseHourlyStat(tx, clusterId, nodeId, timeutil.FormatTime("YmdH", stat.CreatedAt), stat.NsDomainId, stat.NsRecordId, stat.CountRequests, stat.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSRecordHourlyStat 获取单个记录单个小时的统计
|
||||
func (this *NSRecordHourlyStatService) FindNSRecordHourlyStat(ctx context.Context, req *pb.FindNSRecordHourlyStatRequest) (*pb.FindNSRecordHourlyStatResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(req.Hour) == 0 {
|
||||
req.Hour = timeutil.Format("YmdH")
|
||||
} else if !regexp.MustCompile(`^\d{10}$`).MatchString(req.Hour) {
|
||||
return nil, errors.New("invalid hour '" + req.Hour + "'")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSRecordDAO.CheckUserRecord(tx, userId, req.NsRecordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
stat, err := nameservers.SharedNSRecordHourlyStatDAO.FindHourlyStatWithRecordId(tx, req.NsRecordId, req.Hour)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if stat == nil {
|
||||
return &pb.FindNSRecordHourlyStatResponse{NsRecordHourlyStat: nil}, nil
|
||||
}
|
||||
|
||||
return &pb.FindNSRecordHourlyStatResponse{
|
||||
NsRecordHourlyStat: &pb.NSRecordHourlyStat{
|
||||
NsRecordId: req.NsRecordId,
|
||||
Bytes: int64(stat.Bytes),
|
||||
CountRequests: int64(stat.CountRequests),
|
||||
Hour: req.Hour,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindLatestNSRecordsHourlyStats 获取单个记录24小时内的统计
|
||||
func (this *NSRecordHourlyStatService) FindLatestNSRecordsHourlyStats(ctx context.Context, req *pb.FindLatestNSRecordsHourlyStatsRequest) (*pb.FindLatestNSRecordsHourlyStatsResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSRecordDAO.CheckUserRecord(tx, userId, req.NsRecordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
stats, err := nameservers.SharedNSRecordHourlyStatDAO.FindHourlyStatsWithRecordId(tx, req.NsRecordId, timeutil.Format("YmdH", time.Now().Add(-23*time.Hour)), timeutil.Format("YmdH"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbStats = []*pb.NSRecordHourlyStat{}
|
||||
for _, stat := range stats {
|
||||
pbStats = append(pbStats, &pb.NSRecordHourlyStat{
|
||||
NsRecordId: req.NsRecordId,
|
||||
Bytes: int64(stat.Bytes),
|
||||
CountRequests: int64(stat.CountRequests),
|
||||
Hour: stat.Hour,
|
||||
})
|
||||
}
|
||||
return &pb.FindLatestNSRecordsHourlyStatsResponse{
|
||||
NsRecordHourlyStats: pbStats,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindNSRecordHourlyStatWithRecordIds 批量获取一组记录的统计
|
||||
func (this *NSRecordHourlyStatService) FindNSRecordHourlyStatWithRecordIds(ctx context.Context, req *pb.FindNSRecordHourlyStatWithRecordIdsRequest) (*pb.FindNSRecordHourlyStatWithRecordIdsResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(req.Hour) == 0 {
|
||||
req.Hour = timeutil.Format("YmdH")
|
||||
} else if !regexp.MustCompile(`^\d{10}$`).MatchString(req.Hour) {
|
||||
return nil, errors.New("invalid hour '" + req.Hour + "'")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
for _, recordId := range req.NsRecordIds {
|
||||
err = nameservers.SharedNSRecordDAO.CheckUserRecord(tx, userId, recordId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var pbStats = []*pb.NSRecordHourlyStat{}
|
||||
for _, recordId := range req.NsRecordIds {
|
||||
stat, err := nameservers.SharedNSRecordHourlyStatDAO.FindHourlyStatWithRecordId(tx, recordId, req.Hour)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if stat == nil {
|
||||
continue
|
||||
}
|
||||
pbStats = append(pbStats, &pb.NSRecordHourlyStat{
|
||||
NsRecordId: recordId,
|
||||
Bytes: int64(stat.Bytes),
|
||||
CountRequests: int64(stat.CountRequests),
|
||||
Hour: stat.Hour,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FindNSRecordHourlyStatWithRecordIdsResponse{
|
||||
NsRecordHourlyStats: pbStats,
|
||||
}, nil
|
||||
}
|
||||
614
EdgeAPI/internal/rpc/services/nameservers/service_ns_route.go
Normal file
614
EdgeAPI/internal/rpc/services/nameservers/service_ns_route.go
Normal file
@@ -0,0 +1,614 @@
|
||||
// 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
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package nameservers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
// NSRouteCategoryService 线路分类服务
|
||||
type NSRouteCategoryService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateNSRouteCategory 创建线路分类
|
||||
func (this *NSRouteCategoryService) CreateNSRouteCategory(ctx context.Context, req *pb.CreateNSRouteCategoryRequest) (*pb.CreateNSRouteCategoryResponse, error) {
|
||||
// TODO 需要防止用户恶意创建非常多的分类
|
||||
adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
categoryId, err := nameservers.SharedNSRouteCategoryDAO.CreateCategory(tx, adminId, userId, req.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CreateNSRouteCategoryResponse{NsRouteCategoryId: categoryId}, nil
|
||||
}
|
||||
|
||||
// UpdateNSRouteCategory 修改线路分类
|
||||
func (this *NSRouteCategoryService) UpdateNSRouteCategory(ctx context.Context, req *pb.UpdateNSRouteCategoryRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSRouteCategoryDAO.CheckUserCategory(tx, userId, req.NsRouteCategoryId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSRouteCategoryDAO.UpdateCategory(tx, req.NsRouteCategoryId, req.Name, req.IsOn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// DeleteNSRouteCategory 删除线路分类
|
||||
func (this *NSRouteCategoryService) DeleteNSRouteCategory(ctx context.Context, req *pb.DeleteNSRouteCategoryRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSRouteCategoryDAO.CheckUserCategory(tx, userId, req.NsRouteCategoryId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSRouteCategoryDAO.DisableNSRouteCategory(tx, req.NsRouteCategoryId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 重置线路
|
||||
err = nameservers.SharedNSRouteDAO.ResetRoutesCategory(tx, req.NsRouteCategoryId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindAllNSRouteCategories 列出所有线路分类
|
||||
func (this *NSRouteCategoryService) FindAllNSRouteCategories(ctx context.Context, req *pb.FindAllNSRouteCategoriesRequest) (*pb.FindAllNSRouteCategoriesResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
categories, err := nameservers.SharedNSRouteCategoryDAO.FindAllCategories(tx, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pbCategories = []*pb.NSRouteCategory{}
|
||||
for _, category := range categories {
|
||||
pbCategories = append(pbCategories, &pb.NSRouteCategory{
|
||||
Id: int64(category.Id),
|
||||
Name: category.Name,
|
||||
IsOn: category.IsOn,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FindAllNSRouteCategoriesResponse{
|
||||
NsRouteCategories: pbCategories,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNSRouteCategoryOrders 对线路分类进行排序
|
||||
func (this *NSRouteCategoryService) UpdateNSRouteCategoryOrders(ctx context.Context, req *pb.UpdateNSRouteCategoryOrders) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
for _, categoryId := range req.NsRouteCategoryIds {
|
||||
err = nameservers.SharedNSRouteCategoryDAO.CheckUserCategory(tx, userId, categoryId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = nameservers.SharedNSRouteCategoryDAO.UpdateCategoryOrders(tx, userId, req.NsRouteCategoryIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSRouteCategory 查找单个线路分类
|
||||
func (this *NSRouteCategoryService) FindNSRouteCategory(ctx context.Context, req *pb.FindNSRouteCategoryRequest) (*pb.FindNSRouteCategoryResponse, error) {
|
||||
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = nameservers.SharedNSRouteCategoryDAO.CheckUserCategory(tx, userId, req.NsRouteCategoryId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
category, err := nameservers.SharedNSRouteCategoryDAO.FindCategory(tx, req.NsRouteCategoryId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if category == nil {
|
||||
return &pb.FindNSRouteCategoryResponse{
|
||||
NsRouteCategory: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &pb.FindNSRouteCategoryResponse{
|
||||
NsRouteCategory: &pb.NSRouteCategory{
|
||||
Id: int64(category.Id),
|
||||
Name: category.Name,
|
||||
IsOn: category.IsOn,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,370 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build plus
|
||||
|
||||
package nameservers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/accounts"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NSUserPlanService 用户DNS套餐服务
|
||||
type NSUserPlanService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateNSUserPlan 创建用户套餐
|
||||
func (this *NSUserPlanService) CreateNSUserPlan(ctx context.Context, req *pb.CreateNSUserPlanRequest) (*pb.CreateNSUserPlanResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var dayFrom = req.DayFrom
|
||||
var dayTo = req.DayTo
|
||||
|
||||
if !regexputils.YYYYMMDD.MatchString(dayFrom) {
|
||||
return nil, errors.New("invalid dayFrom: " + dayFrom)
|
||||
}
|
||||
if !regexputils.YYYYMMDD.MatchString(dayTo) {
|
||||
return nil, errors.New("invalid dayTo: " + dayTo)
|
||||
}
|
||||
|
||||
if !lists.ContainsString([]string{nameservers.NSUserPlanPeriodUnitMonthly, nameservers.NSUserPlanPeriodUnitYearly}, req.PeriodUnit) {
|
||||
return nil, errors.New("invalid periodUnit: " + req.PeriodUnit)
|
||||
}
|
||||
|
||||
// 检查plan是否存在
|
||||
var tx = this.NullTx()
|
||||
existPlan, err := nameservers.SharedNSPlanDAO.ExistPlan(tx, req.NsPlanId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existPlan {
|
||||
return nil, errors.New("plan '" + types.String(req.NsPlanId) + "' not found")
|
||||
}
|
||||
|
||||
// 用户Plan是否存在
|
||||
var resultUserPlanId int64
|
||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||
userPlan, err := nameservers.SharedNSUserPlanDAO.FindUserPlan(tx, req.UserId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if userPlan == nil {
|
||||
userPlanId, err := nameservers.SharedNSUserPlanDAO.CreateUserPlan(tx, req.UserId, req.NsPlanId, dayFrom, dayTo, req.PeriodUnit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resultUserPlanId = userPlanId
|
||||
} else {
|
||||
err = nameservers.SharedNSUserPlanDAO.UpdateUserPlan(tx, int64(userPlan.Id), req.NsPlanId, dayFrom, dayTo, req.PeriodUnit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CreateNSUserPlanResponse{NsUserPlanId: resultUserPlanId}, nil
|
||||
}
|
||||
|
||||
// UpdateNSUserPlan 修改用户套餐
|
||||
func (this *NSUserPlanService) UpdateNSUserPlan(ctx context.Context, req *pb.UpdateNSUserPlanRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var dayFrom = req.DayFrom
|
||||
var dayTo = req.DayTo
|
||||
|
||||
if !regexputils.YYYYMMDD.MatchString(dayFrom) {
|
||||
return nil, errors.New("invalid dayFrom: " + dayFrom)
|
||||
}
|
||||
if !regexputils.YYYYMMDD.MatchString(dayTo) {
|
||||
return nil, errors.New("invalid dayTo: " + dayTo)
|
||||
}
|
||||
|
||||
if !lists.ContainsString([]string{nameservers.NSUserPlanPeriodUnitMonthly, nameservers.NSUserPlanPeriodUnitYearly}, req.PeriodUnit) {
|
||||
return nil, errors.New("invalid periodUnit: " + req.PeriodUnit)
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = nameservers.SharedNSUserPlanDAO.UpdateUserPlan(tx, req.NsUserPlanId, req.NsPlanId, dayFrom, dayTo, req.PeriodUnit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// DeleteNSUserPlan 删除用户套餐
|
||||
func (this *NSUserPlanService) DeleteNSUserPlan(ctx context.Context, req *pb.DeleteNSUserPlanRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
err = nameservers.SharedNSUserPlanDAO.DisableNSUserPlan(tx, req.NsUserPlanId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNSUserPlan 读取用户套餐
|
||||
func (this *NSUserPlanService) FindNSUserPlan(ctx context.Context, req *pb.FindNSUserPlanRequest) (*pb.FindNSUserPlanResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
var userPlan *nameservers.NSUserPlan
|
||||
if req.NsUserPlanId > 0 {
|
||||
userPlan, err = nameservers.SharedNSUserPlanDAO.FindEnabledNSUserPlan(tx, req.NsUserPlanId)
|
||||
} else if req.UserId > 0 {
|
||||
userPlan, err = nameservers.SharedNSUserPlanDAO.FindUserPlan(tx, req.UserId)
|
||||
} else {
|
||||
return &pb.FindNSUserPlanResponse{NsUserPlan: nil}, nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userPlan == nil {
|
||||
return &pb.FindNSUserPlanResponse{NsUserPlan: nil}, nil
|
||||
}
|
||||
|
||||
plan, err := nameservers.SharedNSPlanDAO.FindEnabledNSPlan(tx, int64(userPlan.PlanId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if plan == nil {
|
||||
return &pb.FindNSUserPlanResponse{NsUserPlan: nil}, nil
|
||||
}
|
||||
|
||||
// user
|
||||
user, err := models.SharedUserDAO.FindEnabledBasicUser(tx, int64(userPlan.UserId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbUser *pb.User
|
||||
if user != nil {
|
||||
pbUser = &pb.User{
|
||||
Id: int64(user.Id),
|
||||
Username: user.Username,
|
||||
Fullname: user.Fullname,
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindNSUserPlanResponse{
|
||||
NsUserPlan: &pb.NSUserPlan{
|
||||
Id: int64(userPlan.Id),
|
||||
NsPlanId: int64(userPlan.PlanId),
|
||||
DayFrom: userPlan.DayFrom,
|
||||
DayTo: userPlan.DayTo,
|
||||
PeriodUnit: userPlan.PeriodUnit,
|
||||
NsPlan: &pb.NSPlan{
|
||||
Id: int64(plan.Id),
|
||||
Name: plan.Name,
|
||||
IsOn: plan.IsOn,
|
||||
MonthlyPrice: float32(plan.MonthlyPrice),
|
||||
YearlyPrice: float32(plan.YearlyPrice),
|
||||
ConfigJSON: plan.Config,
|
||||
},
|
||||
User: pbUser,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CountNSUserPlans 计算用户套餐数量
|
||||
func (this *NSUserPlanService) CountNSUserPlans(ctx context.Context, req *pb.CountNSUserPlansRequest) (*pb.RPCCountResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
count, err := nameservers.SharedNSUserPlanDAO.CountUserPlans(tx, req.UserId, req.NsPlanId, req.PeriodUnit, req.IsExpired, req.ExpireDays)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.SuccessCount(count)
|
||||
}
|
||||
|
||||
// ListNSUserPlans 列出单页套餐
|
||||
func (this *NSUserPlanService) ListNSUserPlans(ctx context.Context, req *pb.ListNSUserPlansRequest) (*pb.ListNSUserPlansResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
userPlans, err := nameservers.SharedNSUserPlanDAO.ListUserPlans(tx, req.UserId, req.NsPlanId, req.PeriodUnit, req.IsExpired, req.ExpireDays, req.Offset, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pbUserPlans = []*pb.NSUserPlan{}
|
||||
for _, userPlan := range userPlans {
|
||||
// plan
|
||||
plan, err := nameservers.SharedNSPlanDAO.FindEnabledNSPlan(tx, int64(userPlan.PlanId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if plan == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// user
|
||||
user, err := models.SharedUserDAO.FindEnabledBasicUser(tx, int64(userPlan.UserId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbUser *pb.User
|
||||
if user != nil {
|
||||
pbUser = &pb.User{
|
||||
Id: int64(user.Id),
|
||||
Username: user.Username,
|
||||
Fullname: user.Fullname,
|
||||
}
|
||||
}
|
||||
|
||||
pbUserPlans = append(pbUserPlans, &pb.NSUserPlan{
|
||||
Id: int64(userPlan.Id),
|
||||
NsPlanId: int64(userPlan.PlanId),
|
||||
UserId: int64(userPlan.UserId),
|
||||
DayFrom: userPlan.DayFrom,
|
||||
DayTo: userPlan.DayTo,
|
||||
PeriodUnit: userPlan.PeriodUnit,
|
||||
NsPlan: &pb.NSPlan{
|
||||
Id: int64(plan.Id),
|
||||
Name: plan.Name,
|
||||
IsOn: plan.IsOn,
|
||||
MonthlyPrice: float32(plan.MonthlyPrice),
|
||||
YearlyPrice: float32(plan.YearlyPrice),
|
||||
ConfigJSON: plan.Config,
|
||||
},
|
||||
User: pbUser,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.ListNSUserPlansResponse{
|
||||
NsUserPlans: pbUserPlans,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BuyNSUserPlan 使用余额购买用户套餐
|
||||
func (this *NSUserPlanService) BuyNSUserPlan(ctx context.Context, req *pb.BuyNSUserPlanRequest) (*pb.BuyNSUserPlanResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
userId = req.UserId
|
||||
|
||||
// 查询套餐
|
||||
var tx *dbs.Tx
|
||||
plan, err := nameservers.SharedNSPlanDAO.FindEnabledNSPlan(tx, req.PlanId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if plan == nil || !plan.IsOn {
|
||||
return nil, errors.New("could not find plan with id '" + types.String(req.PlanId) + "'")
|
||||
}
|
||||
|
||||
var dayFrom = timeutil.Format("Ymd")
|
||||
var dayTo = ""
|
||||
var price float64
|
||||
switch req.Period {
|
||||
case "yearly":
|
||||
price = plan.YearlyPrice
|
||||
dayTo = timeutil.Format("Ymd", time.Now().AddDate(1, 0, 0))
|
||||
case "monthly":
|
||||
price = plan.MonthlyPrice
|
||||
dayTo = timeutil.Format("Ymd", time.Now().AddDate(0, 1, 0))
|
||||
default:
|
||||
return nil, errors.New("invalid period '" + req.Period + "'")
|
||||
}
|
||||
|
||||
var userPlanId int64
|
||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||
// 当前是否有套餐在有效期
|
||||
userPlan, err := nameservers.SharedNSUserPlanDAO.FindUserPlan(tx, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if userPlan != nil && userPlan.IsAvailable() {
|
||||
return errors.New("there is an available user plan yet, you can not buy again")
|
||||
}
|
||||
|
||||
// 如果是0价格,则不允许购买
|
||||
if price <= 0 {
|
||||
return errors.New("invalid plan price")
|
||||
}
|
||||
|
||||
// 先减少余额
|
||||
account, err := accounts.SharedUserAccountDAO.FindUserAccountWithUserId(tx, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if account == nil || account.Total < price {
|
||||
return errors.New("no enough balance to buy the plan")
|
||||
}
|
||||
|
||||
err = accounts.SharedUserAccountDAO.UpdateUserAccount(tx, int64(account.Id), -price, userconfigs.AccountEventTypeBuyNSPlan, "购买DNS套餐\""+plan.Name+"\"", maps.Map{
|
||||
"nsPlanId": plan.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建套餐
|
||||
userPlanId, err = nameservers.SharedNSUserPlanDAO.CreateUserPlan(tx, userId, req.PlanId, dayFrom, dayTo, req.Period)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.BuyNSUserPlanResponse{UserPlanId: userPlanId}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user