增加DNS服务商账号管理

This commit is contained in:
GoEdgeLab
2020-11-11 21:32:25 +08:00
parent 1d1cebbe47
commit 761cb6ca60
17 changed files with 488 additions and 0 deletions

View File

@@ -69,6 +69,10 @@ function build() {
# building api node # building api node
env GOOS=$OS GOARCH=$ARCH go build --ldflags="-s -w" -o $DIST/bin/edge-api $ROOT/../cmd/edge-api/main.go env GOOS=$OS GOARCH=$ARCH go build --ldflags="-s -w" -o $DIST/bin/edge-api $ROOT/../cmd/edge-api/main.go
# delete hidden files
find $DIST -name ".DS_Store" -delete
find $DIST -name ".gitignore" -delete
echo "zip files" echo "zip files"
cd "${DIST}/../" || exit cd "${DIST}/../" || exit
if [ -f "${ZIP}" ]; then if [ -f "${ZIP}" ]; then

View File

@@ -0,0 +1,133 @@
package models
import (
"github.com/TeaOSLab/EdgeAPI/internal/errors"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/types"
"time"
)
const (
DNSProviderStateEnabled = 1 // 已启用
DNSProviderStateDisabled = 0 // 已禁用
)
type DNSProviderDAO dbs.DAO
func NewDNSProviderDAO() *DNSProviderDAO {
return dbs.NewDAO(&DNSProviderDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeDNSProviders",
Model: new(DNSProvider),
PkName: "id",
},
}).(*DNSProviderDAO)
}
var SharedDNSProviderDAO *DNSProviderDAO
func init() {
dbs.OnReady(func() {
SharedDNSProviderDAO = NewDNSProviderDAO()
})
}
// 启用条目
func (this *DNSProviderDAO) EnableDNSProvider(id int64) error {
_, err := this.Query().
Pk(id).
Set("state", DNSProviderStateEnabled).
Update()
return err
}
// 禁用条目
func (this *DNSProviderDAO) DisableDNSProvider(id int64) error {
_, err := this.Query().
Pk(id).
Set("state", DNSProviderStateDisabled).
Update()
return err
}
// 查找启用中的条目
func (this *DNSProviderDAO) FindEnabledDNSProvider(id int64) (*DNSProvider, error) {
result, err := this.Query().
Pk(id).
Attr("state", DNSProviderStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*DNSProvider), err
}
// 创建服务商
func (this *DNSProviderDAO) CreateDNSProvider(providerType string, name string, apiParamsJSON []byte, routesJSON []byte) (int64, error) {
op := NewDNSProviderOperator()
op.Type = providerType
op.Name = name
if len(apiParamsJSON) > 0 {
op.ApiParams = apiParamsJSON
}
if len(routesJSON) > 0 {
op.Routes = routesJSON
}
op.State = DNSProviderStateEnabled
op.DataUpdatedAt = time.Now().Unix()
_, err := this.Save(op)
if err != nil {
return 0, err
}
return types.Int64(op.Id), nil
}
// 修改服务商
func (this *DNSProviderDAO) UpdateDNSProvider(dnsProviderId int64, name string, apiParamsJSON []byte, routesJSON []byte) error {
if dnsProviderId <= 0 {
return errors.New("invalid dnsProviderId")
}
op := NewDNSProviderOperator()
op.Id = dnsProviderId
op.Name = name
// 如果留空则表示不修改
if len(apiParamsJSON) > 0 {
op.ApiParams = apiParamsJSON
}
// 如果留空则表示不修改
if len(routesJSON) > 0 {
op.Routes = routesJSON
}
op.DataUpdatedAt = time.Now().Unix()
_, err := this.Save(op)
if err != nil {
return err
}
return nil
}
// 计算服务商数量
func (this *DNSProviderDAO) CountAllEnabledDNSProviders() (int64, error) {
return this.Query().
State(DNSProviderStateEnabled).
Count()
}
// 列出单页服务商
func (this *DNSProviderDAO) ListEnabledDNSProviders(offset int64, size int64) (result []*DNSProvider, err error) {
_, err = this.Query().
State(DNSProviderStateEnabled).
Offset(offset).
Limit(size).
DescPk().
Slice(&result).
FindAll()
return
}

View File

@@ -0,0 +1,5 @@
package models
import (
_ "github.com/go-sql-driver/mysql"
)

View File

@@ -0,0 +1,30 @@
package models
// DNS服务商
type DNSProvider struct {
Id uint32 `field:"id"` // ID
Name string `field:"name"` // 名称
AdminId uint32 `field:"adminId"` // 管理员ID
Type string `field:"type"` // 供应商类型
ApiParams string `field:"apiParams"` // API参数
CreatedAt uint64 `field:"createdAt"` // 创建时间
State uint8 `field:"state"` // 状态
Routes string `field:"routes"` // 可以使用的线路
DataUpdatedAt uint64 `field:"dataUpdatedAt"` // 数据同步时间
}
type DNSProviderOperator struct {
Id interface{} // ID
Name interface{} // 名称
AdminId interface{} // 管理员ID
Type interface{} // 供应商类型
ApiParams interface{} // API参数
CreatedAt interface{} // 创建时间
State interface{} // 状态
Routes interface{} // 可以使用的线路
DataUpdatedAt interface{} // 数据同步时间
}
func NewDNSProviderOperator() *DNSProviderOperator {
return &DNSProviderOperator{}
}

View File

@@ -0,0 +1 @@
package models

View File

@@ -268,6 +268,25 @@ func (this *NodeClusterDAO) FindAllEnabledClustersWithGrantId(grantId int64) (re
return return
} }
// 计算使用某个DNS服务商的集群数量
func (this *NodeClusterDAO) CountAllEnabledClustersWithDNSProviderId(dnsProviderId int64) (int64, error) {
return this.Query().
State(NodeClusterStateEnabled).
Attr("dnsProviderId", dnsProviderId).
Count()
}
// 获取所有使用某个DNS服务商的集群
func (this *NodeClusterDAO) FindAllEnabledClustersWithDNSProviderId(dnsProviderId int64) (result []*NodeCluster, err error) {
_, err = this.Query().
State(NodeClusterStateEnabled).
Attr("dnsProviderId", dnsProviderId).
Slice(&result).
DescPk().
FindAll()
return
}
// 查找集群的认证ID // 查找集群的认证ID
func (this *NodeClusterDAO) FindClusterGrantId(clusterId int64) (int64, error) { func (this *NodeClusterDAO) FindClusterGrantId(clusterId int64) (int64, error) {
return this.Query(). return this.Query().
@@ -276,6 +295,21 @@ func (this *NodeClusterDAO) FindClusterGrantId(clusterId int64) (int64, error) {
FindInt64Col(0) FindInt64Col(0)
} }
// 查找DNS信息
func (this *NodeClusterDAO) FindClusterDNSInfo(clusterId int64) (*NodeCluster, error) {
one, err := this.Query().
Pk(clusterId).
Result("dnsName", "dnsDomain", "dnsProviderId").
Find()
if err != nil {
return nil, err
}
if one == nil {
return nil, nil
}
return one.(*NodeCluster), nil
}
// 生成唯一ID // 生成唯一ID
func (this *NodeClusterDAO) genUniqueId() (string, error) { func (this *NodeClusterDAO) genUniqueId() (string, error) {
for { for {

View File

@@ -17,6 +17,9 @@ type NodeCluster struct {
UniqueId string `field:"uniqueId"` // 唯一ID UniqueId string `field:"uniqueId"` // 唯一ID
Secret string `field:"secret"` // 密钥 Secret string `field:"secret"` // 密钥
HealthCheck string `field:"healthCheck"` // 健康检查 HealthCheck string `field:"healthCheck"` // 健康检查
DnsProviderId uint32 `field:"dnsProviderId"` // 当前使用的DNS供应商
DnsName string `field:"dnsName"` // DNS名称
DnsDomain string `field:"dnsDomain"` // DNS域
} }
type NodeClusterOperator struct { type NodeClusterOperator struct {
@@ -35,6 +38,9 @@ type NodeClusterOperator struct {
UniqueId interface{} // 唯一ID UniqueId interface{} // 唯一ID
Secret interface{} // 密钥 Secret interface{} // 密钥
HealthCheck interface{} // 健康检查 HealthCheck interface{} // 健康检查
DnsProviderId interface{} // 当前使用的DNS供应商
DnsName interface{} // DNS名称
DnsDomain interface{} // DNS域
} }
func NewNodeClusterOperator() *NodeClusterOperator { func NewNodeClusterOperator() *NodeClusterOperator {

View File

@@ -23,6 +23,7 @@ type Node struct {
State uint8 `field:"state"` // 状态 State uint8 `field:"state"` // 状态
ConnectedAPINodes string `field:"connectedAPINodes"` // 当前连接的API节点 ConnectedAPINodes string `field:"connectedAPINodes"` // 当前连接的API节点
MaxCPU uint32 `field:"maxCPU"` // 可以使用的最多CPU MaxCPU uint32 `field:"maxCPU"` // 可以使用的最多CPU
DnsRoutes string `field:"dnsRoutes"` // DNS线路设置
} }
type NodeOperator struct { type NodeOperator struct {
@@ -47,6 +48,7 @@ type NodeOperator struct {
State interface{} // 状态 State interface{} // 状态
ConnectedAPINodes interface{} // 当前连接的API节点 ConnectedAPINodes interface{} // 当前连接的API节点
MaxCPU interface{} // 可以使用的最多CPU MaxCPU interface{} // 可以使用的最多CPU
DnsRoutes interface{} // DNS线路设置
} }
func NewNodeOperator() *NodeOperator { func NewNodeOperator() *NodeOperator {

View File

@@ -10,6 +10,7 @@ import (
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/rands"
"github.com/iwind/TeaGo/types" "github.com/iwind/TeaGo/types"
"strconv" "strconv"
"strings" "strings"
@@ -138,6 +139,12 @@ func (this *ServerDAO) CreateServer(adminId int64, userId int64, serverType serv
op.GroupIds = groupIdsJSON op.GroupIds = groupIdsJSON
} }
dnsName, err := this.genDNSName()
if err != nil {
return 0, err
}
op.DnsName = dnsName
op.Version = 1 op.Version = 1
op.IsOn = 1 op.IsOn = 1
op.State = ServerStateEnabled op.State = ServerStateEnabled
@@ -795,3 +802,19 @@ func (this *ServerDAO) CountAllEnabledServersWithGroupId(groupId int64) (int64,
func (this *ServerDAO) createEvent() error { func (this *ServerDAO) createEvent() error {
return SharedSysEventDAO.CreateEvent(NewServerChangeEvent()) return SharedSysEventDAO.CreateEvent(NewServerChangeEvent())
} }
// 生成DNS Name
func (this *ServerDAO) genDNSName() (string, error) {
for {
dnsName := rands.HexString(8)
exist, err := this.Query().
Attr("dnsName", dnsName).
Exist()
if err != nil {
return "", err
}
if !exist {
return dnsName, nil
}
}
}

View File

@@ -4,6 +4,7 @@ import (
"crypto/md5" "crypto/md5"
"encoding/json" "encoding/json"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/logs" "github.com/iwind/TeaGo/logs"
"testing" "testing"
) )
@@ -42,3 +43,12 @@ func TestNewServerDAO_md5(t *testing.T) {
h := m.Sum(nil) h := m.Sum(nil)
t.Logf("%x", h) t.Logf("%x", h)
} }
func TestServerDAO_genDNSName(t *testing.T) {
dbs.NotifyReady()
dnsName, err := SharedServerDAO.genDNSName()
if err != nil {
t.Fatal(err)
}
t.Log("dnsName:", dnsName)
}

View File

@@ -27,6 +27,7 @@ type Server struct {
Version uint32 `field:"version"` // 版本号 Version uint32 `field:"version"` // 版本号
CreatedAt uint64 `field:"createdAt"` // 创建时间 CreatedAt uint64 `field:"createdAt"` // 创建时间
State uint8 `field:"state"` // 状态 State uint8 `field:"state"` // 状态
DnsName string `field:"dnsName"` // DNS名称
} }
type ServerOperator struct { type ServerOperator struct {
@@ -55,6 +56,7 @@ type ServerOperator struct {
Version interface{} // 版本号 Version interface{} // 版本号
CreatedAt interface{} // 创建时间 CreatedAt interface{} // 创建时间
State interface{} // 状态 State interface{} // 状态
DnsName interface{} // DNS名称
} }
func NewServerOperator() *ServerOperator { func NewServerOperator() *ServerOperator {

View File

@@ -0,0 +1,7 @@
package dnsproviders
// DNS操作接口
type ProviderInterface interface {
// 检查账号
}

View File

@@ -0,0 +1,25 @@
package dnsproviders
import "github.com/iwind/TeaGo/maps"
type ProviderType = string
const (
ProviderTypeDNSPod ProviderType = "dnspod"
)
var AllProviderTypes = []maps.Map{
{
"name": "DNSPod",
"code": ProviderTypeDNSPod,
},
}
func FindProviderTypeName(providerType string) string {
for _, t := range AllProviderTypes {
if t.GetString("code") == providerType {
return t.GetString("name")
}
}
return ""
}

View File

@@ -181,6 +181,7 @@ func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) err
pb.RegisterIPListServiceServer(rpcServer, &services.IPListService{}) pb.RegisterIPListServiceServer(rpcServer, &services.IPListService{})
pb.RegisterIPItemServiceServer(rpcServer, &services.IPItemService{}) pb.RegisterIPItemServiceServer(rpcServer, &services.IPItemService{})
pb.RegisterLogServiceServer(rpcServer, &services.LogService{}) pb.RegisterLogServiceServer(rpcServer, &services.LogService{})
pb.RegisterDNSProviderServiceServer(rpcServer, &services.DNSProviderService{})
err := rpcServer.Serve(listener) err := rpcServer.Serve(listener)
if err != nil { if err != nil {
return errors.New("[API]start rpc failed: " + err.Error()) return errors.New("[API]start rpc failed: " + err.Error())

View File

@@ -0,0 +1,146 @@
package services
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/dnsproviders"
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// DNS服务商相关服务
type DNSProviderService struct {
}
// 创建服务商
func (this *DNSProviderService) CreateDNSProvider(ctx context.Context, req *pb.CreateDNSProviderRequest) (*pb.CreateDNSProviderResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
if err != nil {
return nil, err
}
providerId, err := models.SharedDNSProviderDAO.CreateDNSProvider(req.Type, req.Name, req.ApiParamsJSON, req.RoutesJSON)
if err != nil {
return nil, err
}
return &pb.CreateDNSProviderResponse{DnsProviderId: providerId}, nil
}
// 修改服务商
func (this *DNSProviderService) UpdateDNSProvider(ctx context.Context, req *pb.UpdateDNSProviderRequest) (*pb.RPCUpdateSuccess, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
if err != nil {
return nil, err
}
err = models.SharedDNSProviderDAO.UpdateDNSProvider(req.DnsProviderId, req.Name, req.ApiParamsJSON, req.RoutesJSON)
if err != nil {
return nil, err
}
return rpcutils.RPCUpdateSuccess()
}
// 计算服务商数量
func (this *DNSProviderService) CountAllEnabledDNSProviders(ctx context.Context, req *pb.CountAllEnabledDNSProvidersRequest) (*pb.CountAllEnabledDNSProvidersResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
if err != nil {
return nil, err
}
count, err := models.SharedDNSProviderDAO.CountAllEnabledDNSProviders()
if err != nil {
return nil, err
}
return &pb.CountAllEnabledDNSProvidersResponse{Count: count}, nil
}
// 列出单页服务商信息
func (this *DNSProviderService) ListEnabledDNSProviders(ctx context.Context, req *pb.ListEnabledDNSProvidersRequest) (*pb.ListEnabledDNSProvidersResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
if err != nil {
return nil, err
}
providers, err := models.SharedDNSProviderDAO.ListEnabledDNSProviders(req.Offset, req.Size)
if err != nil {
return nil, err
}
result := []*pb.DNSProvider{}
for _, provider := range providers {
result = append(result, &pb.DNSProvider{
Id: int64(provider.Id),
Name: provider.Name,
Type: provider.Type,
TypeName: dnsproviders.FindProviderTypeName(provider.Type),
ApiParamsJSON: []byte(provider.ApiParams),
RoutesJSON: []byte(provider.Routes),
DataUpdatedAt: int64(provider.DataUpdatedAt),
})
}
return &pb.ListEnabledDNSProvidersResponse{DnsProviders: result}, nil
}
// 删除服务商
func (this *DNSProviderService) DeleteDNSProvider(ctx context.Context, req *pb.DeleteDNSProviderRequest) (*pb.RPCDeleteSuccess, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
if err != nil {
return nil, err
}
err = models.SharedDNSProviderDAO.DisableDNSProvider(req.DnsProviderId)
if err != nil {
return nil, err
}
return rpcutils.RPCDeleteSuccess()
}
// 查找单个服务商
func (this *DNSProviderService) FindEnabledDNSProvider(ctx context.Context, req *pb.FindEnabledDNSProviderRequest) (*pb.FindEnabledDNSProviderResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
if err != nil {
return nil, err
}
provider, err := models.SharedDNSProviderDAO.FindEnabledDNSProvider(req.DnsProviderId)
if err != nil {
return nil, err
}
if provider == nil {
return &pb.FindEnabledDNSProviderResponse{DnsProvider: nil}, nil
}
return &pb.FindEnabledDNSProviderResponse{DnsProvider: &pb.DNSProvider{
Id: int64(provider.Id),
Name: provider.Name,
Type: provider.Type,
TypeName: dnsproviders.FindProviderTypeName(provider.Type),
ApiParamsJSON: []byte(provider.ApiParams),
RoutesJSON: []byte(provider.Routes),
DataUpdatedAt: int64(provider.DataUpdatedAt),
}}, nil
}
// 取得所有服务商类型
func (this *DNSProviderService) FindAllDNSProviderTypes(ctx context.Context, req *pb.FindAllDNSProviderTypesRequest) (*pb.FindAllDNSProviderTypesResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
if err != nil {
return nil, err
}
result := []*pb.DNSProviderType{}
for _, t := range dnsproviders.AllProviderTypes {
result = append(result, &pb.DNSProviderType{
Name: t.GetString("name"),
Code: t.GetString("code"),
})
}
return &pb.FindAllDNSProviderTypesResponse{ProviderTypes: result}, nil
}

View File

@@ -4,6 +4,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/db/models" "github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/dnsproviders"
"github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/errors"
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils" rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
"github.com/TeaOSLab/EdgeAPI/internal/tasks" "github.com/TeaOSLab/EdgeAPI/internal/tasks"
@@ -350,3 +351,59 @@ func (this *NodeClusterService) FindAllEnabledNodeClustersWithGrantId(ctx contex
} }
return &pb.FindAllEnabledNodeClustersWithGrantIdResponse{Clusters: result}, nil return &pb.FindAllEnabledNodeClustersWithGrantIdResponse{Clusters: result}, nil
} }
// 查找集群的DNS配置
func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, req *pb.FindEnabledNodeClusterDNSRequest) (*pb.FindEnabledNodeClusterDNSResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
if err != nil {
return nil, err
}
dnsInfo, err := models.SharedNodeClusterDAO.FindClusterDNSInfo(req.NodeClusterId)
if err != nil {
return nil, err
}
if dnsInfo == nil {
return &pb.FindEnabledNodeClusterDNSResponse{
Name: "",
Domain: "",
Provider: nil,
}, nil
}
provider, err := models.SharedDNSProviderDAO.FindEnabledDNSProvider(int64(dnsInfo.DnsProviderId))
if err != nil {
return nil, err
}
var pbProvider *pb.DNSProvider = nil
if provider != nil {
pbProvider = &pb.DNSProvider{
Id: int64(provider.Id),
Type: provider.Type,
TypeName: dnsproviders.FindProviderTypeName(provider.Type),
}
}
return &pb.FindEnabledNodeClusterDNSResponse{
Name: dnsInfo.DnsName,
Domain: dnsInfo.DnsDomain,
Provider: pbProvider,
}, nil
}
// 计算使用某个DNS服务商的集群数量
func (this *NodeClusterService) CountAllEnabledNodeClustersWithDNSProviderId(ctx context.Context, req *pb.CountAllEnabledNodeClustersWithDNSProviderIdRequest) (*pb.CountAllEnabledNodeClustersWithDNSProviderIdResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
if err != nil {
return nil, err
}
count, err := models.SharedNodeClusterDAO.CountAllEnabledClustersWithDNSProviderId(req.DnsProviderId)
if err != nil {
return nil, err
}
return &pb.CountAllEnabledNodeClustersWithDNSProviderIdResponse{Count: count}, nil
}

View File

@@ -420,6 +420,7 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
ExcludeNodes: []byte(server.ExcludeNodes), ExcludeNodes: []byte(server.ExcludeNodes),
ServerNamesJON: []byte(server.ServerNames), ServerNamesJON: []byte(server.ServerNames),
CreatedAt: int64(server.CreatedAt), CreatedAt: int64(server.CreatedAt),
DnsName: server.DnsName,
Cluster: &pb.NodeCluster{ Cluster: &pb.NodeCluster{
Id: int64(server.ClusterId), Id: int64(server.ClusterId),
Name: clusterName, Name: clusterName,
@@ -515,6 +516,7 @@ func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEn
Type: server.Type, Type: server.Type,
Name: server.Name, Name: server.Name,
Description: server.Description, Description: server.Description,
DnsName: server.DnsName,
Config: []byte(server.Config), Config: []byte(server.Config),
ServerNamesJON: []byte(server.ServerNames), ServerNamesJON: []byte(server.ServerNames),
HttpJSON: []byte(server.Http), HttpJSON: []byte(server.Http),