mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-14 12:20:27 +08:00
增加认证节点管理
This commit is contained in:
@@ -332,6 +332,10 @@ func (this *RPCClient) AuthorityKeyRPC() pb.AuthorityKeyServiceClient {
|
|||||||
return pb.NewAuthorityKeyServiceClient(this.pickConn())
|
return pb.NewAuthorityKeyServiceClient(this.pickConn())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *RPCClient) AuthorityNodeRPC() pb.AuthorityNodeServiceClient {
|
||||||
|
return pb.NewAuthorityNodeServiceClient(this.pickConn())
|
||||||
|
}
|
||||||
|
|
||||||
// Context 构造Admin上下文
|
// Context 构造Admin上下文
|
||||||
func (this *RPCClient) Context(adminId int64) context.Context {
|
func (this *RPCClient) Context(adminId int64) context.Context {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type IndexAction struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *IndexAction) Init() {
|
func (this *IndexAction) Init() {
|
||||||
this.Nav("", "", "")
|
this.Nav("", "", "index")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *IndexAction) RunGet(params struct{}) {
|
func (this *IndexAction) RunGet(params struct{}) {
|
||||||
@@ -47,5 +47,23 @@ func (this *IndexAction) RunGet(params struct{}) {
|
|||||||
}
|
}
|
||||||
this.Data["key"] = keyMap
|
this.Data["key"] = keyMap
|
||||||
|
|
||||||
|
// 检查是否有认证节点,如果没有认证节点,则自动生成一个
|
||||||
|
countResp, err := this.RPC().AuthorityNodeRPC().CountAllEnabledAuthorityNodes(this.AdminContext(), &pb.CountAllEnabledAuthorityNodesRequest{})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if countResp.Count == 0 {
|
||||||
|
_, err = this.RPC().AuthorityNodeRPC().CreateAuthorityNode(this.AdminContext(), &pb.CreateAuthorityNodeRequest{
|
||||||
|
Name: "默认节点",
|
||||||
|
Description: "系统自动生成的默认节点",
|
||||||
|
IsOn: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package nodes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||||
|
"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 {
|
||||||
|
NodeId int64
|
||||||
|
}) {
|
||||||
|
// TODO 检查权限
|
||||||
|
|
||||||
|
_, err := this.RPC().AuthorityNodeRPC().DeleteAuthorityNode(this.AdminContext(), &pb.DeleteAuthorityNodeRequest{NodeId: params.NodeId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建日志
|
||||||
|
defer this.CreateLog(oplogs.LevelInfo, "删除认证节点 %d", params.NodeId)
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package nodes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Helper struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHelper() *Helper {
|
||||||
|
return &Helper{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Helper) BeforeAction(action *actions.ActionObject) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package nodes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/logs"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IndexAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) Init() {
|
||||||
|
this.Nav("", "node", "node")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) RunGet(params struct{}) {
|
||||||
|
countResp, err := this.RPC().AuthorityNodeRPC().CountAllEnabledAuthorityNodes(this.AdminContext(), &pb.CountAllEnabledAuthorityNodesRequest{})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
count := countResp.Count
|
||||||
|
page := this.NewPage(count)
|
||||||
|
this.Data["page"] = page.AsHTML()
|
||||||
|
|
||||||
|
nodeMaps := []maps.Map{}
|
||||||
|
if count > 0 {
|
||||||
|
nodesResp, err := this.RPC().AuthorityNodeRPC().ListEnabledAuthorityNodes(this.AdminContext(), &pb.ListEnabledAuthorityNodesRequest{
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, node := range nodesResp.Nodes {
|
||||||
|
// 状态
|
||||||
|
status := &nodeconfigs.NodeStatus{}
|
||||||
|
if len(node.StatusJSON) > 0 {
|
||||||
|
err = json.Unmarshal(node.StatusJSON, &status)
|
||||||
|
if err != nil {
|
||||||
|
logs.Error(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
status.IsActive = status.IsActive && time.Now().Unix()-status.UpdatedAt <= 60 // N秒之内认为活跃
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeMaps = append(nodeMaps, maps.Map{
|
||||||
|
"id": node.Id,
|
||||||
|
"isOn": node.IsOn,
|
||||||
|
"name": node.Name,
|
||||||
|
"status": maps.Map{
|
||||||
|
"isActive": status.IsActive,
|
||||||
|
"updatedAt": status.UpdatedAt,
|
||||||
|
"hostname": status.Hostname,
|
||||||
|
"cpuUsage": status.CPUUsage,
|
||||||
|
"cpuUsageText": fmt.Sprintf("%.2f%%", status.CPUUsage*100),
|
||||||
|
"memUsage": status.MemoryUsage,
|
||||||
|
"memUsageText": fmt.Sprintf("%.2f%%", status.MemoryUsage*100),
|
||||||
|
"buildVersion": status.BuildVersion,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Data["nodes"] = nodeMaps
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package nodes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/authority/nodes/node"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/settingutils"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||||
|
"github.com/iwind/TeaGo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||||
|
server.
|
||||||
|
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeSetting)).
|
||||||
|
Helper(NewHelper()).
|
||||||
|
Helper(settingutils.NewAdvancedHelper("authority")).
|
||||||
|
Prefix("/settings/authority/nodes").
|
||||||
|
Get("", new(IndexAction)).
|
||||||
|
GetPost("/node/createPopup", new(node.CreatePopupAction)).
|
||||||
|
Post("/delete", new(DeleteAction)).
|
||||||
|
EndAll()
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreatePopupAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreatePopupAction) Init() {
|
||||||
|
this.Nav("", "node", "create")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreatePopupAction) RunGet(params struct{}) {
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreatePopupAction) RunPost(params struct {
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
IsOn bool
|
||||||
|
|
||||||
|
Must *actions.Must
|
||||||
|
}) {
|
||||||
|
params.Must.
|
||||||
|
Field("name", params.Name).
|
||||||
|
Require("请输入认证节点名称")
|
||||||
|
|
||||||
|
createResp, err := this.RPC().AuthorityNodeRPC().CreateAuthorityNode(this.AdminContext(), &pb.CreateAuthorityNodeRequest{
|
||||||
|
Name: params.Name,
|
||||||
|
Description: params.Description,
|
||||||
|
IsOn: params.IsOn,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建日志
|
||||||
|
defer this.CreateLog(oplogs.LevelInfo, "创建认证节点 %d", createResp.NodeId)
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Helper struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHelper() *Helper {
|
||||||
|
return &Helper{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Helper) BeforeAction(action *actions.ActionObject) (goNext bool) {
|
||||||
|
if action.Request.Method != http.MethodGet {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IndexAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) Init() {
|
||||||
|
this.Nav("", "", "index")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) RunGet(params struct {
|
||||||
|
NodeId int64
|
||||||
|
}) {
|
||||||
|
nodeResp, err := this.RPC().AuthorityNodeRPC().FindEnabledAuthorityNode(this.AdminContext(), &pb.FindEnabledAuthorityNodeRequest{NodeId: params.NodeId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
node := nodeResp.Node
|
||||||
|
if node == nil {
|
||||||
|
this.NotFound("authorityNode", params.NodeId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data["node"] = maps.Map{
|
||||||
|
"id": node.Id,
|
||||||
|
"name": node.Name,
|
||||||
|
"description": node.Description,
|
||||||
|
"isOn": node.IsOn,
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/settingutils"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||||
|
"github.com/iwind/TeaGo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||||
|
server.
|
||||||
|
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeSetting)).
|
||||||
|
Helper(settingutils.NewAdvancedHelper("authority")).
|
||||||
|
Prefix("/settings/authority/nodes/node").
|
||||||
|
|
||||||
|
// 节点相关
|
||||||
|
Helper(NewHelper()).
|
||||||
|
Get("", new(IndexAction)).
|
||||||
|
GetPost("/update", new(UpdateAction)).
|
||||||
|
Get("/install", new(InstallAction)).
|
||||||
|
|
||||||
|
EndAll()
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InstallAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *InstallAction) Init() {
|
||||||
|
this.Nav("", "", "install")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *InstallAction) RunGet(params struct {
|
||||||
|
NodeId int64
|
||||||
|
}) {
|
||||||
|
// 认证节点信息
|
||||||
|
nodeResp, err := this.RPC().AuthorityNodeRPC().FindEnabledAuthorityNode(this.AdminContext(), &pb.FindEnabledAuthorityNodeRequest{NodeId: params.NodeId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
node := nodeResp.Node
|
||||||
|
if node == nil {
|
||||||
|
this.NotFound("authorityNode", params.NodeId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data["node"] = maps.Map{
|
||||||
|
"id": node.Id,
|
||||||
|
"name": node.Name,
|
||||||
|
"uniqueId": node.UniqueId,
|
||||||
|
"secret": node.Secret,
|
||||||
|
}
|
||||||
|
|
||||||
|
// API节点列表
|
||||||
|
apiNodesResp, err := this.RPC().APINodeRPC().FindAllEnabledAPINodes(this.AdminContext(), &pb.FindAllEnabledAPINodesRequest{})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
apiNodes := apiNodesResp.Nodes
|
||||||
|
apiEndpoints := []string{}
|
||||||
|
for _, apiNode := range apiNodes {
|
||||||
|
if !apiNode.IsOn {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
apiEndpoints = append(apiEndpoints, apiNode.AccessAddrs...)
|
||||||
|
}
|
||||||
|
this.Data["apiEndpoints"] = "\"" + strings.Join(apiEndpoints, "\", \"") + "\""
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UpdateAction) Init() {
|
||||||
|
this.Nav("", "", "update")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UpdateAction) RunGet(params struct {
|
||||||
|
NodeId int64
|
||||||
|
}) {
|
||||||
|
nodeResp, err := this.RPC().AuthorityNodeRPC().FindEnabledAuthorityNode(this.AdminContext(), &pb.FindEnabledAuthorityNodeRequest{
|
||||||
|
NodeId: params.NodeId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
node := nodeResp.Node
|
||||||
|
if node == nil {
|
||||||
|
this.WriteString("要操作的节点不存在")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data["node"] = maps.Map{
|
||||||
|
"id": node.Id,
|
||||||
|
"name": node.Name,
|
||||||
|
"description": node.Description,
|
||||||
|
"isOn": node.IsOn,
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存基础设置
|
||||||
|
func (this *UpdateAction) RunPost(params struct {
|
||||||
|
NodeId int64
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
IsOn bool
|
||||||
|
|
||||||
|
Must *actions.Must
|
||||||
|
}) {
|
||||||
|
params.Must.
|
||||||
|
Field("name", params.Name).
|
||||||
|
Require("请输入认证节点名称")
|
||||||
|
|
||||||
|
_, err := this.RPC().AuthorityNodeRPC().UpdateAuthorityNode(this.AdminContext(), &pb.UpdateAuthorityNodeRequest{
|
||||||
|
NodeId: params.NodeId,
|
||||||
|
Name: params.Name,
|
||||||
|
Description: params.Description,
|
||||||
|
IsOn: params.IsOn,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建日志
|
||||||
|
defer this.CreateLog(oplogs.LevelInfo, "修改认证节点 %d", params.NodeId)
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -85,6 +85,8 @@ import (
|
|||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/stat"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/stat"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/authority"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/authority"
|
||||||
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/authority/nodes"
|
||||||
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/authority/nodes/node"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/backup"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/backup"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/database"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/database"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/ip-library"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/ip-library"
|
||||||
|
|||||||
4
web/views/@default/settings/authority/@menu.html
Normal file
4
web/views/@default/settings/authority/@menu.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<first-menu>
|
||||||
|
<menu-item href="/settings/authority" code="index">认证信息</menu-item>
|
||||||
|
<menu-item href="/settings/authority/nodes" code="node">认证节点</menu-item>
|
||||||
|
</first-menu>
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
{$layout}
|
{$layout}
|
||||||
|
{$template "menu"}
|
||||||
|
|
||||||
<div class="ui message warning" v-if="key == null">认证之后,可以使用企业版功能,当前你还没有认证,<a href="http://edge.teaos.cn/docs/Plus/Authority/Index.md" target="_blank">[在这里看认证方法]</a>。</div>
|
<div class="ui message warning" v-if="key == null">认证之后,可以使用企业版功能,当前你还没有认证,<a href="http://edge.teaos.cn/docs/Plus/Authority/Index.md" target="_blank">[在这里看认证方法]</a>。</div>
|
||||||
|
|
||||||
|
|||||||
50
web/views/@default/settings/authority/nodes/index.html
Normal file
50
web/views/@default/settings/authority/nodes/index.html
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{$layout}
|
||||||
|
{$template "../menu"}
|
||||||
|
|
||||||
|
<!--<first-menu>
|
||||||
|
<a href="" class="item" @click.prevent="createNode()">[添加节点]</a>
|
||||||
|
</first-menu>-->
|
||||||
|
|
||||||
|
<p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p>
|
||||||
|
|
||||||
|
<table class="ui table selectable celled" v-if="nodes.length > 0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>节点名称</th>
|
||||||
|
<th class="width6 center">版本号</th>
|
||||||
|
<th class="width5 center">CPU</th>
|
||||||
|
<th class="width5 center">内存</th>
|
||||||
|
<th class="center width10">状态</th>
|
||||||
|
<th class="two op">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr v-for="node in nodes">
|
||||||
|
<td>{{node.name}}</td>
|
||||||
|
<td class="center">
|
||||||
|
<span v-if="node.status.buildVersion.length > 0">v{{node.status.buildVersion}}</span>
|
||||||
|
<span v-else class="disabled">-</span>
|
||||||
|
</td>
|
||||||
|
<td class="center">
|
||||||
|
<span v-if="node.status.isActive" :class="{red:node.status.cpuUsage > 0.80}">{{node.status.cpuUsageText}}</span>
|
||||||
|
<span v-else class="disabled">-</span>
|
||||||
|
</td>
|
||||||
|
<td class="center">
|
||||||
|
<span v-if="node.status.isActive" :class="{red:node.status.memUsage > 0.80}">{{node.status.memUsageText}}</span>
|
||||||
|
<span v-else class="disabled">-</span>
|
||||||
|
</td>
|
||||||
|
<td class="center">
|
||||||
|
<span v-if="!node.isOn"><label-on :v-is-on="node.isOn"></label-on></span>
|
||||||
|
<div v-else-if="node.status.isActive">
|
||||||
|
<span class="green">运行中</span>
|
||||||
|
</div>
|
||||||
|
<span v-else-if="node.status.updatedAt > 0" class="red">已断开</span>
|
||||||
|
<span v-else-if="node.status.updatedAt == 0" class="red">未连接</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a :href="'/settings/authority/nodes/node?nodeId=' + node.id">详情</a>
|
||||||
|
<a href="" @click.prevent="deleteNode(node.id)">删除</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="page" v-html="page"></div>
|
||||||
26
web/views/@default/settings/authority/nodes/index.js
Normal file
26
web/views/@default/settings/authority/nodes/index.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
// 创建节点
|
||||||
|
this.createNode = function () {
|
||||||
|
teaweb.popup("/settings/authority/nodes/node/createPopup", {
|
||||||
|
width: "50em",
|
||||||
|
height: "30em",
|
||||||
|
callback: function () {
|
||||||
|
teaweb.success("保存成功", function () {
|
||||||
|
teaweb.reload()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除节点
|
||||||
|
this.deleteNode = function (nodeId) {
|
||||||
|
let that = this
|
||||||
|
teaweb.confirm("确定要删除此节点吗?", function () {
|
||||||
|
that.$post("/settings/authority/nodes/delete")
|
||||||
|
.params({
|
||||||
|
nodeId: nodeId
|
||||||
|
})
|
||||||
|
.refresh()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<first-menu>
|
||||||
|
<menu-item href="/settings/authority/nodes">节点列表</menu-item>
|
||||||
|
<span class="item">|</span>
|
||||||
|
<menu-item :href="'/settings/authority/nodes/node?nodeId=' + node.id" code="index">"{{node.name}}"详情</menu-item>
|
||||||
|
<menu-item :href="'/settings/authority/nodes/node/install?nodeId=' + node.id" code="install">安装节点</menu-item>
|
||||||
|
<menu-item :href="'/settings/authority/nodes/node/update?nodeId=' + node.id" code="update">修改节点</menu-item>
|
||||||
|
</first-menu>
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{$layout "layout_popup"}
|
||||||
|
|
||||||
|
<h3>添加认证节点</h3>
|
||||||
|
<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
|
||||||
|
<table class="ui table selectable definition">
|
||||||
|
<tr>
|
||||||
|
<td class="title">节点名称 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="name" maxlength="100" ref="focus"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||||
|
</tr>
|
||||||
|
<tbody v-show="moreOptionsVisible">
|
||||||
|
<tr>
|
||||||
|
<td>描述</td>
|
||||||
|
<td>
|
||||||
|
<textarea name="description" maxlength="200" rows="3"></textarea>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>是否启用</td>
|
||||||
|
<td>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input type="checkbox" name="isOn" value="1" checked="checked"/>
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<submit-btn></submit-btn>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
|
||||||
|
})
|
||||||
24
web/views/@default/settings/authority/nodes/node/index.html
Normal file
24
web/views/@default/settings/authority/nodes/node/index.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{$layout}
|
||||||
|
{$template "menu"}
|
||||||
|
|
||||||
|
<table class="ui table selectable definition">
|
||||||
|
<tr>
|
||||||
|
<td class="title">节点名称</td>
|
||||||
|
<td>
|
||||||
|
{{node.name}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>状态</td>
|
||||||
|
<td>
|
||||||
|
<label-on :v-is-on="node.isOn"></label-on>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>描述</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="node.description.length > 0">{{node.description}}</span>
|
||||||
|
<span v-else class="disabled">暂时还没有描述。</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{$layout}
|
||||||
|
{$template "menu"}
|
||||||
|
|
||||||
|
<h3>安装步骤</h3>
|
||||||
|
<ol class="ui list">
|
||||||
|
<li>按照下面的配置信息替换<code-label>configs/api.yaml</code-label>内容</li>
|
||||||
|
<li>使用<code-label>bin/edge-authority start</code-label>启动节点</li>
|
||||||
|
<li>可以在<code-label>logs/run.log</code-label>中查看启动是否有异常</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
<h3>配置信息</h3>
|
||||||
|
<table class="ui table definition selectable">
|
||||||
|
<tr>
|
||||||
|
<td class="title">configs/api.yaml<em><br/><download-link :v-element="'api-code'" :v-file="'api.yaml'">[下载]</download-link></em></td>
|
||||||
|
<td>
|
||||||
|
<pre id="api-code">rpc:
|
||||||
|
endpoints: [ {{apiEndpoints}} ]
|
||||||
|
nodeId: "{{node.uniqueId}}"
|
||||||
|
secret: "{{node.secret}}"</pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
37
web/views/@default/settings/authority/nodes/node/update.html
Normal file
37
web/views/@default/settings/authority/nodes/node/update.html
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{$layout}
|
||||||
|
|
||||||
|
{$template "menu"}
|
||||||
|
|
||||||
|
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||||
|
<input type="hidden" name="nodeId" :value="node.id"/>
|
||||||
|
<input type="hidden" name="sslPolicyId" :value="node.sslPolicyId"/>
|
||||||
|
<table class="ui table selectable definition">
|
||||||
|
<tr>
|
||||||
|
<td class="title">节点名称 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="name" maxlength="100" ref="focus" v-model="node.name"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||||
|
</tr>
|
||||||
|
<tbody v-show="moreOptionsVisible">
|
||||||
|
<tr>
|
||||||
|
<td>描述</td>
|
||||||
|
<td>
|
||||||
|
<textarea name="description" maxlength="200" rows="3" v-model="node.description"></textarea>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>是否启用</td>
|
||||||
|
<td>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input type="checkbox" name="isOn" value="1" v-model="node.isOn"/>
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<submit-btn></submit-btn>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.success = NotifySuccess("保存成功", "/settings/authority/nodes/node?nodeId=" + this.node.id)
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user