mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-09 00:20:26 +08:00
DNS服务支持密钥管理/“域名服务”改为“自建DNS”
This commit is contained in:
@@ -15,7 +15,7 @@ func main() {
|
|||||||
app := apps.NewAppCmd().
|
app := apps.NewAppCmd().
|
||||||
Version(teaconst.Version).
|
Version(teaconst.Version).
|
||||||
Product(teaconst.ProductName).
|
Product(teaconst.ProductName).
|
||||||
Usage(teaconst.ProcessName+" [-v|start|stop|restart|service|daemon|reset|recover]").
|
Usage(teaconst.ProcessName+" [-v|start|stop|restart|service|daemon|reset|recover|demo]").
|
||||||
Option("-h", "show this help").
|
Option("-h", "show this help").
|
||||||
Option("-v", "show version").
|
Option("-v", "show version").
|
||||||
Option("start", "start the service").
|
Option("start", "start the service").
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ func AllModuleMaps() []maps.Map {
|
|||||||
}
|
}
|
||||||
if teaconst.IsPlus {
|
if teaconst.IsPlus {
|
||||||
m = append(m, maps.Map{
|
m = append(m, maps.Map{
|
||||||
"name": "域名服务",
|
"name": "自建DNS",
|
||||||
"code": AdminModuleCodeNS,
|
"code": AdminModuleCodeNS,
|
||||||
"url": "/ns",
|
"url": "/ns",
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -388,6 +388,10 @@ func (this *RPCClient) NSRecordRPC() pb.NSRecordServiceClient {
|
|||||||
return pb.NewNSRecordServiceClient(this.pickConn())
|
return pb.NewNSRecordServiceClient(this.pickConn())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *RPCClient) NSKeyRPC() pb.NSKeyServiceClient {
|
||||||
|
return pb.NewNSKeyServiceClient(this.pickConn())
|
||||||
|
}
|
||||||
|
|
||||||
func (this *RPCClient) NSRouteRPC() pb.NSRouteServiceClient {
|
func (this *RPCClient) NSRouteRPC() pb.NSRouteServiceClient {
|
||||||
return pb.NewNSRouteServiceClient(this.pickConn())
|
return pb.NewNSRouteServiceClient(this.pickConn())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package domains
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains/domainutils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
)
|
)
|
||||||
@@ -19,6 +20,14 @@ func (this *DomainAction) Init() {
|
|||||||
func (this *DomainAction) RunGet(params struct {
|
func (this *DomainAction) RunGet(params struct {
|
||||||
DomainId int64
|
DomainId int64
|
||||||
}) {
|
}) {
|
||||||
|
err := domainutils.InitDomain(this.Parent(), params.DomainId)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var countRecords = this.Data.GetMap("domain").GetInt64("countRecords")
|
||||||
|
var countKeys = this.Data.GetMap("domain").GetInt64("countKeys")
|
||||||
|
|
||||||
// 域名信息
|
// 域名信息
|
||||||
domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: params.DomainId})
|
domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: params.DomainId})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -55,6 +64,8 @@ func (this *DomainAction) RunGet(params struct {
|
|||||||
"isOn": domain.IsOn,
|
"isOn": domain.IsOn,
|
||||||
"cluster": clusterMap,
|
"cluster": clusterMap,
|
||||||
"user": userMap,
|
"user": userMap,
|
||||||
|
"countRecords": countRecords,
|
||||||
|
"countKeys": countKeys,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
|
|||||||
55
internal/web/actions/default/ns/domains/domainutils/utils.go
Normal file
55
internal/web/actions/default/ns/domains/domainutils/utils.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package domainutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitDomain 初始化域名信息
|
||||||
|
func InitDomain(parent *actionutils.ParentAction, domainId int64) error {
|
||||||
|
rpcClient, err := rpc.SharedRPC()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
domainResp, err := rpcClient.NSDomainRPC().FindEnabledNSDomain(parent.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: domainId})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var domain = domainResp.NsDomain
|
||||||
|
if domain == nil {
|
||||||
|
return errors.New("InitDomain: can not find domain with id '" + types.String(domainId) + "'")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录数量
|
||||||
|
countRecordsResp, err := rpcClient.NSRecordRPC().CountAllEnabledNSRecords(parent.AdminContext(), &pb.CountAllEnabledNSRecordsRequest{
|
||||||
|
NsDomainId: domainId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var countRecords = countRecordsResp.Count
|
||||||
|
|
||||||
|
// Key数量
|
||||||
|
countKeysResp, err := rpcClient.NSKeyRPC().CountAllEnabledNSKeys(parent.AdminContext(), &pb.CountAllEnabledNSKeysRequest{
|
||||||
|
NsDomainId: domainId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var countKeys = countKeysResp.Count
|
||||||
|
|
||||||
|
parent.Data["domain"] = maps.Map{
|
||||||
|
"id": domain.Id,
|
||||||
|
"name": domain.Name,
|
||||||
|
"countRecords": countRecords,
|
||||||
|
"countKeys": countKeys,
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
86
internal/web/actions/default/ns/domains/keys/createPopup.go
Normal file
86
internal/web/actions/default/ns/domains/keys/createPopup.go
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreatePopupAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreatePopupAction) Init() {
|
||||||
|
this.Nav("", "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreatePopupAction) RunGet(params struct {
|
||||||
|
DomainId int64
|
||||||
|
}) {
|
||||||
|
this.Data["domainId"] = params.DomainId
|
||||||
|
|
||||||
|
// 所有算法
|
||||||
|
var algorithmMaps = []maps.Map{}
|
||||||
|
for _, algo := range dnsconfigs.FindAllKeyAlgorithmTypes() {
|
||||||
|
algorithmMaps = append(algorithmMaps, maps.Map{
|
||||||
|
"name": algo.Name,
|
||||||
|
"code": algo.Code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.Data["algorithms"] = algorithmMaps
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreatePopupAction) RunPost(params struct {
|
||||||
|
DomainId int64
|
||||||
|
Name string
|
||||||
|
Algo string
|
||||||
|
Secret string
|
||||||
|
SecretType string
|
||||||
|
|
||||||
|
Must *actions.Must
|
||||||
|
CSRF *actionutils.CSRF
|
||||||
|
}) {
|
||||||
|
var keyId int64 = 0
|
||||||
|
defer func() {
|
||||||
|
this.CreateLogInfo("创建DNS密钥 %d", keyId)
|
||||||
|
}()
|
||||||
|
|
||||||
|
params.Must.
|
||||||
|
Field("name", params.Name).
|
||||||
|
Require("请输入密钥名称").
|
||||||
|
Field("algo", params.Algo).
|
||||||
|
Require("请选择算法").
|
||||||
|
Field("secret", params.Secret).
|
||||||
|
Require("请输入密码")
|
||||||
|
|
||||||
|
// 校验密码
|
||||||
|
if params.SecretType == dnsconfigs.NSKeySecretTypeBase64 {
|
||||||
|
_, err := base64.StdEncoding.DecodeString(params.Secret)
|
||||||
|
if err != nil {
|
||||||
|
this.FailField("secret", "请输入BASE64格式的密码或者选择明文")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createResp, err := this.RPC().NSKeyRPC().CreateNSKey(this.AdminContext(), &pb.CreateNSKeyRequest{
|
||||||
|
NsDomainId: params.DomainId,
|
||||||
|
NsZoneId: 0,
|
||||||
|
Name: params.Name,
|
||||||
|
Algo: params.Algo,
|
||||||
|
Secret: params.Secret,
|
||||||
|
SecretType: params.SecretType,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
keyId = createResp.NsKeyId
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
26
internal/web/actions/default/ns/domains/keys/delete.go
Normal file
26
internal/web/actions/default/ns/domains/keys/delete.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeleteAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *DeleteAction) RunPost(params struct {
|
||||||
|
KeyId int64
|
||||||
|
}) {
|
||||||
|
defer this.CreateLogInfo("删除DNS密钥 %d", params.KeyId)
|
||||||
|
|
||||||
|
_, err := this.RPC().NSKeyRPC().DeleteNSKey(this.AdminContext(), &pb.DeleteNSKeyRequest{NsKeyId: params.KeyId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||||
|
"github.com/iwind/TeaGo/rands"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GenerateSecretAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *GenerateSecretAction) RunPost(params struct {
|
||||||
|
SecretType string
|
||||||
|
}) {
|
||||||
|
switch params.SecretType {
|
||||||
|
case dnsconfigs.NSKeySecretTypeClear:
|
||||||
|
this.Data["secret"] = rands.HexString(128)
|
||||||
|
case dnsconfigs.NSKeySecretTypeBase64:
|
||||||
|
this.Data["secret"] = base64.StdEncoding.EncodeToString([]byte(rands.HexString(128)))
|
||||||
|
default:
|
||||||
|
this.Data["secret"] = rands.HexString(128)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
68
internal/web/actions/default/ns/domains/keys/index.go
Normal file
68
internal/web/actions/default/ns/domains/keys/index.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains/domainutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IndexAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) Init() {
|
||||||
|
this.Nav("", "", "key")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) RunGet(params struct {
|
||||||
|
DomainId int64
|
||||||
|
}) {
|
||||||
|
// 初始化域名信息
|
||||||
|
err := domainutils.InitDomain(this.Parent(), params.DomainId)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数量
|
||||||
|
countResp, err := this.RPC().NSKeyRPC().CountAllEnabledNSKeys(this.AdminContext(), &pb.CountAllEnabledNSKeysRequest{
|
||||||
|
NsDomainId: params.DomainId,
|
||||||
|
NsZoneId: 0,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var page = this.NewPage(countResp.Count)
|
||||||
|
this.Data["page"] = page.AsHTML()
|
||||||
|
|
||||||
|
// 列表
|
||||||
|
keysResp, err := this.RPC().NSKeyRPC().ListEnabledNSKeys(this.AdminContext(), &pb.ListEnabledNSKeysRequest{
|
||||||
|
NsDomainId: params.DomainId,
|
||||||
|
NsZoneId: 0,
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var keyMaps = []maps.Map{}
|
||||||
|
for _, key := range keysResp.NsKeys {
|
||||||
|
keyMaps = append(keyMaps, maps.Map{
|
||||||
|
"id": key.Id,
|
||||||
|
"name": key.Name,
|
||||||
|
"secret": key.Secret,
|
||||||
|
"secretTypeName": dnsconfigs.FindKeySecretTypeName(key.SecretType),
|
||||||
|
"algoName": dnsconfigs.FindKeyAlgorithmTypeName(key.Algo),
|
||||||
|
"isOn": key.IsOn,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.Data["keys"] = keyMaps
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
100
internal/web/actions/default/ns/domains/keys/updatePopup.go
Normal file
100
internal/web/actions/default/ns/domains/keys/updatePopup.go
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdatePopupAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UpdatePopupAction) Init() {
|
||||||
|
this.Nav("", "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UpdatePopupAction) RunGet(params struct {
|
||||||
|
KeyId int64
|
||||||
|
}) {
|
||||||
|
keyResp, err := this.RPC().NSKeyRPC().FindEnabledNSKey(this.AdminContext(), &pb.FindEnabledNSKeyRequest{NsKeyId: params.KeyId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var key = keyResp.NsKey
|
||||||
|
if key == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data["key"] = maps.Map{
|
||||||
|
"id": key.Id,
|
||||||
|
"name": key.Name,
|
||||||
|
"algo": key.Algo,
|
||||||
|
"secret": key.Secret,
|
||||||
|
"secretType": key.SecretType,
|
||||||
|
"isOn": key.IsOn,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 所有算法
|
||||||
|
var algorithmMaps = []maps.Map{}
|
||||||
|
for _, algo := range dnsconfigs.FindAllKeyAlgorithmTypes() {
|
||||||
|
algorithmMaps = append(algorithmMaps, maps.Map{
|
||||||
|
"name": algo.Name,
|
||||||
|
"code": algo.Code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.Data["algorithms"] = algorithmMaps
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UpdatePopupAction) RunPost(params struct {
|
||||||
|
KeyId int64
|
||||||
|
Name string
|
||||||
|
Algo string
|
||||||
|
Secret string
|
||||||
|
SecretType string
|
||||||
|
IsOn bool
|
||||||
|
|
||||||
|
Must *actions.Must
|
||||||
|
CSRF *actionutils.CSRF
|
||||||
|
}) {
|
||||||
|
this.CreateLogInfo("修改DNS密钥 %d", params.KeyId)
|
||||||
|
|
||||||
|
params.Must.
|
||||||
|
Field("name", params.Name).
|
||||||
|
Require("请输入密钥名称").
|
||||||
|
Field("algo", params.Algo).
|
||||||
|
Require("请选择算法").
|
||||||
|
Field("secret", params.Secret).
|
||||||
|
Require("请输入密码")
|
||||||
|
|
||||||
|
// 校验密码
|
||||||
|
if params.SecretType == dnsconfigs.NSKeySecretTypeBase64 {
|
||||||
|
_, err := base64.StdEncoding.DecodeString(params.Secret)
|
||||||
|
if err != nil {
|
||||||
|
this.FailField("secret", "请输入BASE64格式的密码或者选择明文")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := this.RPC().NSKeyRPC().UpdateNSKey(this.AdminContext(), &pb.UpdateNSKeyRequest{
|
||||||
|
NsKeyId: params.KeyId,
|
||||||
|
Name: params.Name,
|
||||||
|
Algo: params.Algo,
|
||||||
|
Secret: params.Secret,
|
||||||
|
SecretType: params.SecretType,
|
||||||
|
IsOn: params.IsOn,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ package records
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains/domainutils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
@@ -23,25 +24,16 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
Keyword string
|
Keyword string
|
||||||
RouteId int64
|
RouteId int64
|
||||||
}) {
|
}) {
|
||||||
this.Data["type"] = params.Type
|
// 初始化域名信息
|
||||||
this.Data["keyword"] = params.Keyword
|
err := domainutils.InitDomain(this.Parent(), params.DomainId)
|
||||||
this.Data["routeId"] = params.RouteId
|
|
||||||
|
|
||||||
// 域名信息
|
|
||||||
domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: params.DomainId})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
domain := domainResp.NsDomain
|
|
||||||
if domain == nil {
|
this.Data["type"] = params.Type
|
||||||
this.NotFound("nsDomain", params.DomainId)
|
this.Data["keyword"] = params.Keyword
|
||||||
return
|
this.Data["routeId"] = params.RouteId
|
||||||
}
|
|
||||||
this.Data["domain"] = maps.Map{
|
|
||||||
"id": domain.Id,
|
|
||||||
"name": domain.Name,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 记录
|
// 记录
|
||||||
countResp, err := this.RPC().NSRecordRPC().CountAllEnabledNSRecords(this.AdminContext(), &pb.CountAllEnabledNSRecordsRequest{
|
countResp, err := this.RPC().NSRecordRPC().CountAllEnabledNSRecords(this.AdminContext(), &pb.CountAllEnabledNSRecordsRequest{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package domains
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains/domainutils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/iwind/TeaGo/actions"
|
"github.com/iwind/TeaGo/actions"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
@@ -20,6 +21,15 @@ func (this *UpdateAction) Init() {
|
|||||||
func (this *UpdateAction) RunGet(params struct {
|
func (this *UpdateAction) RunGet(params struct {
|
||||||
DomainId int64
|
DomainId int64
|
||||||
}) {
|
}) {
|
||||||
|
// 初始化域名信息
|
||||||
|
err := domainutils.InitDomain(this.Parent(), params.DomainId)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var countRecords = this.Data.GetMap("domain").GetInt64("countRecords")
|
||||||
|
var countKeys = this.Data.GetMap("domain").GetInt64("countKeys")
|
||||||
|
|
||||||
// 域名信息
|
// 域名信息
|
||||||
domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: params.DomainId})
|
domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: params.DomainId})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -49,6 +59,8 @@ func (this *UpdateAction) RunGet(params struct {
|
|||||||
"isOn": domain.IsOn,
|
"isOn": domain.IsOn,
|
||||||
"clusterId": clusterId,
|
"clusterId": clusterId,
|
||||||
"userId": userId,
|
"userId": userId,
|
||||||
|
"countRecords": countRecords,
|
||||||
|
"countKeys": countKeys,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package ns
|
|||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains/keys"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains/records"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains/records"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||||
"github.com/iwind/TeaGo"
|
"github.com/iwind/TeaGo"
|
||||||
@@ -23,6 +24,14 @@ func init() {
|
|||||||
Get("/domain", new(domains.DomainAction)).
|
Get("/domain", new(domains.DomainAction)).
|
||||||
GetPost("/update", new(domains.UpdateAction)).
|
GetPost("/update", new(domains.UpdateAction)).
|
||||||
|
|
||||||
|
// 域名密钥
|
||||||
|
Prefix("/ns/domains/keys").
|
||||||
|
Get("", new(keys.IndexAction)).
|
||||||
|
GetPost("/createPopup", new(keys.CreatePopupAction)).
|
||||||
|
GetPost("/updatePopup", new(keys.UpdatePopupAction)).
|
||||||
|
Post("/delete", new(keys.DeleteAction)).
|
||||||
|
Post("/generateSecret", new(keys.GenerateSecretAction)).
|
||||||
|
|
||||||
// 记录相关
|
// 记录相关
|
||||||
Prefix("/ns/domains/records").
|
Prefix("/ns/domains/records").
|
||||||
Get("", new(records.IndexAction)).
|
Get("", new(records.IndexAction)).
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
|
|||||||
{
|
{
|
||||||
"code": "ns",
|
"code": "ns",
|
||||||
"module": configloaders.AdminModuleCodeNS,
|
"module": configloaders.AdminModuleCodeNS,
|
||||||
"name": "域名服务",
|
"name": "自建DNS",
|
||||||
"subtitle": "域名列表",
|
"subtitle": "域名列表",
|
||||||
"icon": "cubes",
|
"icon": "cubes",
|
||||||
"isOn": teaconst.IsPlus,
|
"isOn": teaconst.IsPlus,
|
||||||
|
|||||||
@@ -215,6 +215,10 @@ window.teaweb = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
popup: function (url, options) {
|
popup: function (url, options) {
|
||||||
|
if (url != null && url.length > 0 && url.substring(0, 1) == '.') {
|
||||||
|
url = Tea.url(url)
|
||||||
|
}
|
||||||
|
|
||||||
if (options == null) {
|
if (options == null) {
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
<menu-item href="/ns">所有域名</menu-item>
|
<menu-item href="/ns">所有域名</menu-item>
|
||||||
<span class="item disabled">|</span>
|
<span class="item disabled">|</span>
|
||||||
<menu-item :href="'/ns/domains/domain?domainId=' + domain.id" code="index">详情<span class="grey small">({{domain.name}})</span></menu-item>
|
<menu-item :href="'/ns/domains/domain?domainId=' + domain.id" code="index">详情<span class="grey small">({{domain.name}})</span></menu-item>
|
||||||
<menu-item :href="'/ns/domains/records?domainId=' + domain.id" code="record">记录</menu-item>
|
<menu-item :href="'/ns/domains/records?domainId=' + domain.id" code="record">记录({{domain.countRecords}})</menu-item>
|
||||||
|
<menu-item :href="'/ns/domains/keys?domainId=' + domain.id" code="key">密钥({{domain.countKeys}})</menu-item>
|
||||||
<menu-item :href="'/ns/domains/update?domainId=' + domain.id" code="update">修改</menu-item>
|
<menu-item :href="'/ns/domains/update?domainId=' + domain.id" code="update">修改</menu-item>
|
||||||
</first-menu>
|
</first-menu>
|
||||||
40
web/views/@default/ns/domains/keys/createPopup.html
Normal file
40
web/views/@default/ns/domains/keys/createPopup.html
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{$layout "layout_popup"}
|
||||||
|
|
||||||
|
<h3>创建密钥</h3>
|
||||||
|
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||||
|
<csrf-token></csrf-token>
|
||||||
|
<input type="hidden" name="domainId" :value="domainId"/>
|
||||||
|
<table class="ui table definition selectable">
|
||||||
|
<tr>
|
||||||
|
<td class="title">密钥名称 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="name" ref="focus"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>算法 *</td>
|
||||||
|
<td>
|
||||||
|
<select class="ui dropdown auto-width" name="algo">
|
||||||
|
<option value="">[选择算法]</option>
|
||||||
|
<option v-for="algo in algorithms" :value="algo.code">{{algo.name}}</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>密码 *</td>
|
||||||
|
<td>
|
||||||
|
<div style="margin-bottom: 1em">
|
||||||
|
<radio name="secretType" value="clear" :v-value="'clear'" v-model="secretType">明文密码</radio>
|
||||||
|
|
||||||
|
<radio name="secretType" value="base64" :v-value="'base64'" v-model="secretType">Base64密码</radio>
|
||||||
|
</div>
|
||||||
|
<textarea name="secret" maxlength="256" v-model="secret" rows="3"></textarea>
|
||||||
|
<p class="comment" v-if="secretType == 'clear'">客户端需要将明文转换为BASE64使用。</p>
|
||||||
|
<div style="margin-top: 1em">
|
||||||
|
<a href="" @click.prevent="generateSecret">[随机生成]</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<submit-btn></submit-btn>
|
||||||
|
</form>
|
||||||
20
web/views/@default/ns/domains/keys/createPopup.js
Normal file
20
web/views/@default/ns/domains/keys/createPopup.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.secretType = "clear"
|
||||||
|
this.secret = ""
|
||||||
|
|
||||||
|
this.$delay(function () {
|
||||||
|
this.$watch("secretType", function () {
|
||||||
|
this.secret = ""
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.generateSecret = function () {
|
||||||
|
this.$post(".generateSecret")
|
||||||
|
.params({
|
||||||
|
secretType: this.secretType
|
||||||
|
})
|
||||||
|
.success(function (resp) {
|
||||||
|
this.secret = resp.data.secret
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
38
web/views/@default/ns/domains/keys/index.html
Normal file
38
web/views/@default/ns/domains/keys/index.html
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{$layout}
|
||||||
|
{$template "../domain_menu"}
|
||||||
|
|
||||||
|
<second-menu>
|
||||||
|
<menu-item @click.prevent="createKey">[创建密钥]</menu-item>
|
||||||
|
</second-menu>
|
||||||
|
|
||||||
|
<tip-message-box>这里的密钥可以用于TSIG通讯校验。</tip-message-box>
|
||||||
|
|
||||||
|
<p class="comment" v-if="keys.length == 0">暂时还没有密钥。</p>
|
||||||
|
|
||||||
|
<table class="ui table celled selectable" v-if="keys.length > 0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="two wide">密钥名称</th>
|
||||||
|
<th class="two wide">算法</th>
|
||||||
|
<th>密码</th>
|
||||||
|
<th class="two wide">密码类型</th>
|
||||||
|
<th class="two wide">状态</th>
|
||||||
|
<th class="two op">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr v-for="key in keys">
|
||||||
|
<td>{{key.name}}</td>
|
||||||
|
<td>{{key.algoName}}</td>
|
||||||
|
<td>{{key.secret}}</td>
|
||||||
|
<td>{{key.secretTypeName}}</td>
|
||||||
|
<td>
|
||||||
|
<label-on :v-is-on="key.isOn"></label-on>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="" @click.prevent="updateKey(key.id)">修改</a>
|
||||||
|
<a href="" @click.prevent="deleteKey(key.id)">删除</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="page" v-html="page"></div>
|
||||||
31
web/views/@default/ns/domains/keys/index.js
Normal file
31
web/views/@default/ns/domains/keys/index.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.createKey = function () {
|
||||||
|
teaweb.popup(Tea.url(".createPopup?domainId=" + this.domain.id), {
|
||||||
|
height: "24em",
|
||||||
|
callback: function () {
|
||||||
|
teaweb.successRefresh("保存成功")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateKey = function (keyId) {
|
||||||
|
teaweb.popup(Tea.url(".updatePopup?keyId=" + keyId), {
|
||||||
|
height: "26em",
|
||||||
|
callback: function () {
|
||||||
|
teaweb.successRefresh("保存成功")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.deleteKey = function (keyId) {
|
||||||
|
teaweb.confirm("确定要删除这个密钥吗?", function () {
|
||||||
|
this.$post(".delete")
|
||||||
|
.params({
|
||||||
|
keyId: keyId
|
||||||
|
})
|
||||||
|
.success(function () {
|
||||||
|
teaweb.successRefresh("删除成功")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
46
web/views/@default/ns/domains/keys/updatePopup.html
Normal file
46
web/views/@default/ns/domains/keys/updatePopup.html
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{$layout "layout_popup"}
|
||||||
|
|
||||||
|
<h3>修改密钥</h3>
|
||||||
|
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||||
|
<csrf-token></csrf-token>
|
||||||
|
<input type="hidden" name="keyId" :value="key.id"/>
|
||||||
|
<table class="ui table definition selectable">
|
||||||
|
<tr>
|
||||||
|
<td class="title">密钥名称 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="name" ref="focus" v-model="key.name"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>算法 *</td>
|
||||||
|
<td>
|
||||||
|
<select class="ui dropdown auto-width" name="algo" v-model="key.algo">
|
||||||
|
<option value="">[选择算法]</option>
|
||||||
|
<option v-for="algo in algorithms" :value="algo.code">{{algo.name}}</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>密码 *</td>
|
||||||
|
<td>
|
||||||
|
<div style="margin-bottom: 1em">
|
||||||
|
<radio name="secretType" value="clear" :v-value="'clear'" v-model="secretType">明文密码</radio>
|
||||||
|
|
||||||
|
<radio name="secretType" value="base64" :v-value="'base64'" v-model="secretType">Base64密码</radio>
|
||||||
|
</div>
|
||||||
|
<textarea name="secret" maxlength="256" v-model="secret" rows="3"></textarea>
|
||||||
|
<p class="comment" v-if="secretType == 'clear'">客户端需要将明文转换为BASE64使用。</p>
|
||||||
|
<div style="margin-top: 1em">
|
||||||
|
<a href="" @click.prevent="generateSecret">[随机生成]</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>是否启用</td>
|
||||||
|
<td>
|
||||||
|
<checkbox name="isOn" v-model="key.isOn"></checkbox>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<submit-btn></submit-btn>
|
||||||
|
</form>
|
||||||
20
web/views/@default/ns/domains/keys/updatePopup.js
Normal file
20
web/views/@default/ns/domains/keys/updatePopup.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.secretType = this.key.secretType
|
||||||
|
this.secret = this.key.secret
|
||||||
|
|
||||||
|
this.$delay(function () {
|
||||||
|
this.$watch("secretType", function () {
|
||||||
|
this.secret = ""
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.generateSecret = function () {
|
||||||
|
this.$post(".generateSecret")
|
||||||
|
.params({
|
||||||
|
secretType: this.secretType
|
||||||
|
})
|
||||||
|
.success(function (resp) {
|
||||||
|
this.secret = resp.data.secret
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user