diff --git a/cmd/edge-admin/main.go b/cmd/edge-admin/main.go
index fc907f70..6ec7eca2 100644
--- a/cmd/edge-admin/main.go
+++ b/cmd/edge-admin/main.go
@@ -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").
diff --git a/internal/configloaders/admin_module.go b/internal/configloaders/admin_module.go
index b09c68ff..683006e1 100644
--- a/internal/configloaders/admin_module.go
+++ b/internal/configloaders/admin_module.go
@@ -182,7 +182,7 @@ func AllModuleMaps() []maps.Map {
}
if teaconst.IsPlus {
m = append(m, maps.Map{
- "name": "域名服务",
+ "name": "自建DNS",
"code": AdminModuleCodeNS,
"url": "/ns",
})
diff --git a/internal/rpc/rpc_client.go b/internal/rpc/rpc_client.go
index a5dd8c46..eda79b11 100644
--- a/internal/rpc/rpc_client.go
+++ b/internal/rpc/rpc_client.go
@@ -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())
}
diff --git a/internal/web/actions/default/ns/domains/domain.go b/internal/web/actions/default/ns/domains/domain.go
index 2704e4b3..d8361271 100644
--- a/internal/web/actions/default/ns/domains/domain.go
+++ b/internal/web/actions/default/ns/domains/domain.go
@@ -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 {
@@ -50,11 +59,13 @@ func (this *DomainAction) RunGet(params struct {
}
this.Data["domain"] = maps.Map{
- "id": domain.Id,
- "name": domain.Name,
- "isOn": domain.IsOn,
- "cluster": clusterMap,
- "user": userMap,
+ "id": domain.Id,
+ "name": domain.Name,
+ "isOn": domain.IsOn,
+ "cluster": clusterMap,
+ "user": userMap,
+ "countRecords": countRecords,
+ "countKeys": countKeys,
}
this.Show()
diff --git a/internal/web/actions/default/ns/domains/domainutils/utils.go b/internal/web/actions/default/ns/domains/domainutils/utils.go
new file mode 100644
index 00000000..10285832
--- /dev/null
+++ b/internal/web/actions/default/ns/domains/domainutils/utils.go
@@ -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
+}
diff --git a/internal/web/actions/default/ns/domains/keys/createPopup.go b/internal/web/actions/default/ns/domains/keys/createPopup.go
new file mode 100644
index 00000000..d1d77212
--- /dev/null
+++ b/internal/web/actions/default/ns/domains/keys/createPopup.go
@@ -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()
+}
diff --git a/internal/web/actions/default/ns/domains/keys/delete.go b/internal/web/actions/default/ns/domains/keys/delete.go
new file mode 100644
index 00000000..d76f63a5
--- /dev/null
+++ b/internal/web/actions/default/ns/domains/keys/delete.go
@@ -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()
+}
diff --git a/internal/web/actions/default/ns/domains/keys/generateSecret.go b/internal/web/actions/default/ns/domains/keys/generateSecret.go
new file mode 100644
index 00000000..972c6c52
--- /dev/null
+++ b/internal/web/actions/default/ns/domains/keys/generateSecret.go
@@ -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()
+}
diff --git a/internal/web/actions/default/ns/domains/keys/index.go b/internal/web/actions/default/ns/domains/keys/index.go
new file mode 100644
index 00000000..40695051
--- /dev/null
+++ b/internal/web/actions/default/ns/domains/keys/index.go
@@ -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()
+}
diff --git a/internal/web/actions/default/ns/domains/keys/updatePopup.go b/internal/web/actions/default/ns/domains/keys/updatePopup.go
new file mode 100644
index 00000000..ef48e8d7
--- /dev/null
+++ b/internal/web/actions/default/ns/domains/keys/updatePopup.go
@@ -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()
+}
diff --git a/internal/web/actions/default/ns/domains/records/index.go b/internal/web/actions/default/ns/domains/records/index.go
index cee18c39..9692d71a 100644
--- a/internal/web/actions/default/ns/domains/records/index.go
+++ b/internal/web/actions/default/ns/domains/records/index.go
@@ -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{
diff --git a/internal/web/actions/default/ns/domains/update.go b/internal/web/actions/default/ns/domains/update.go
index d78b0f82..44c307e5 100644
--- a/internal/web/actions/default/ns/domains/update.go
+++ b/internal/web/actions/default/ns/domains/update.go
@@ -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 {
@@ -44,11 +54,13 @@ func (this *UpdateAction) RunGet(params struct {
}
this.Data["domain"] = maps.Map{
- "id": domain.Id,
- "name": domain.Name,
- "isOn": domain.IsOn,
- "clusterId": clusterId,
- "userId": userId,
+ "id": domain.Id,
+ "name": domain.Name,
+ "isOn": domain.IsOn,
+ "clusterId": clusterId,
+ "userId": userId,
+ "countRecords": countRecords,
+ "countKeys": countKeys,
}
this.Show()
diff --git a/internal/web/actions/default/ns/init.go b/internal/web/actions/default/ns/init.go
index 73e42924..4336f53d 100644
--- a/internal/web/actions/default/ns/init.go
+++ b/internal/web/actions/default/ns/init.go
@@ -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)).
diff --git a/internal/web/helpers/user_must_auth.go b/internal/web/helpers/user_must_auth.go
index dfdf85ba..7e06d5e0 100644
--- a/internal/web/helpers/user_must_auth.go
+++ b/internal/web/helpers/user_must_auth.go
@@ -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,
diff --git a/web/public/js/utils.js b/web/public/js/utils.js
index f8296d44..b5b0e4aa 100644
--- a/web/public/js/utils.js
+++ b/web/public/js/utils.js
@@ -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 = {};
}
diff --git a/web/views/@default/ns/domains/@domain_menu.html b/web/views/@default/ns/domains/@domain_menu.html
index ac7f25db..3efd9210 100644
--- a/web/views/@default/ns/domains/@domain_menu.html
+++ b/web/views/@default/ns/domains/@domain_menu.html
@@ -2,6 +2,7 @@
暂时还没有密钥。
+ +| 密钥名称 | +算法 | +密码 | +密码类型 | +状态 | +操作 | +
|---|---|---|---|---|---|
| {{key.name}} | +{{key.algoName}} | +{{key.secret}} | +{{key.secretTypeName}} | +
+ |
+ + 修改 + 删除 + | +