mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-12 11:20:27 +08:00
DNS服务支持密钥管理/“域名服务”改为“自建DNS”
This commit is contained in:
@@ -15,7 +15,7 @@ func main() {
|
||||
app := apps.NewAppCmd().
|
||||
Version(teaconst.Version).
|
||||
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("-v", "show version").
|
||||
Option("start", "start the service").
|
||||
|
||||
@@ -182,7 +182,7 @@ func AllModuleMaps() []maps.Map {
|
||||
}
|
||||
if teaconst.IsPlus {
|
||||
m = append(m, maps.Map{
|
||||
"name": "域名服务",
|
||||
"name": "自建DNS",
|
||||
"code": AdminModuleCodeNS,
|
||||
"url": "/ns",
|
||||
})
|
||||
|
||||
@@ -388,6 +388,10 @@ func (this *RPCClient) NSRecordRPC() pb.NSRecordServiceClient {
|
||||
return pb.NewNSRecordServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NSKeyRPC() pb.NSKeyServiceClient {
|
||||
return pb.NewNSKeyServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NSRouteRPC() pb.NSRouteServiceClient {
|
||||
return pb.NewNSRouteServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package domains
|
||||
|
||||
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/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
@@ -19,6 +20,14 @@ func (this *DomainAction) Init() {
|
||||
func (this *DomainAction) RunGet(params struct {
|
||||
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})
|
||||
if err != nil {
|
||||
@@ -55,6 +64,8 @@ func (this *DomainAction) RunGet(params struct {
|
||||
"isOn": domain.IsOn,
|
||||
"cluster": clusterMap,
|
||||
"user": userMap,
|
||||
"countRecords": countRecords,
|
||||
"countKeys": countKeys,
|
||||
}
|
||||
|
||||
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 (
|
||||
"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"
|
||||
@@ -23,25 +24,16 @@ func (this *IndexAction) RunGet(params struct {
|
||||
Keyword string
|
||||
RouteId int64
|
||||
}) {
|
||||
this.Data["type"] = params.Type
|
||||
this.Data["keyword"] = params.Keyword
|
||||
this.Data["routeId"] = params.RouteId
|
||||
|
||||
// 域名信息
|
||||
domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: params.DomainId})
|
||||
// 初始化域名信息
|
||||
err := domainutils.InitDomain(this.Parent(), params.DomainId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
domain := domainResp.NsDomain
|
||||
if domain == nil {
|
||||
this.NotFound("nsDomain", params.DomainId)
|
||||
return
|
||||
}
|
||||
this.Data["domain"] = maps.Map{
|
||||
"id": domain.Id,
|
||||
"name": domain.Name,
|
||||
}
|
||||
|
||||
this.Data["type"] = params.Type
|
||||
this.Data["keyword"] = params.Keyword
|
||||
this.Data["routeId"] = params.RouteId
|
||||
|
||||
// 记录
|
||||
countResp, err := this.RPC().NSRecordRPC().CountAllEnabledNSRecords(this.AdminContext(), &pb.CountAllEnabledNSRecordsRequest{
|
||||
|
||||
@@ -4,6 +4,7 @@ package domains
|
||||
|
||||
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/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
@@ -20,6 +21,15 @@ func (this *UpdateAction) Init() {
|
||||
func (this *UpdateAction) RunGet(params struct {
|
||||
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})
|
||||
if err != nil {
|
||||
@@ -49,6 +59,8 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
"isOn": domain.IsOn,
|
||||
"clusterId": clusterId,
|
||||
"userId": userId,
|
||||
"countRecords": countRecords,
|
||||
"countKeys": countKeys,
|
||||
}
|
||||
|
||||
this.Show()
|
||||
|
||||
@@ -3,6 +3,7 @@ package ns
|
||||
import (
|
||||
"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/keys"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains/records"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
@@ -23,6 +24,14 @@ func init() {
|
||||
Get("/domain", new(domains.DomainAction)).
|
||||
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").
|
||||
Get("", new(records.IndexAction)).
|
||||
|
||||
@@ -257,7 +257,7 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
|
||||
{
|
||||
"code": "ns",
|
||||
"module": configloaders.AdminModuleCodeNS,
|
||||
"name": "域名服务",
|
||||
"name": "自建DNS",
|
||||
"subtitle": "域名列表",
|
||||
"icon": "cubes",
|
||||
"isOn": teaconst.IsPlus,
|
||||
|
||||
@@ -215,6 +215,10 @@ window.teaweb = {
|
||||
}
|
||||
},
|
||||
popup: function (url, options) {
|
||||
if (url != null && url.length > 0 && url.substring(0, 1) == '.') {
|
||||
url = Tea.url(url)
|
||||
}
|
||||
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<menu-item href="/ns">所有域名</menu-item>
|
||||
<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/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>
|
||||
</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