mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2026-04-30 03:15:19 +08:00
提供管理界面的HTTP/HTTPS修改功能
This commit is contained in:
12
internal/web/actions/default/about/init.go
Normal file
12
internal/web/actions/default/about/init.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package about
|
||||
|
||||
import "github.com/iwind/TeaGo"
|
||||
|
||||
func init() {
|
||||
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||
server.
|
||||
Prefix("/about").
|
||||
Get("/qq", new(QqAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
15
internal/web/actions/default/about/qq.go
Normal file
15
internal/web/actions/default/about/qq.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package about
|
||||
|
||||
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
|
||||
type QqAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *QqAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *QqAction) RunGet(params struct{}) {
|
||||
this.Show()
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 检查变更的集群列表
|
||||
@@ -19,47 +18,20 @@ func (this *CheckChangeAction) Init() {
|
||||
func (this *CheckChangeAction) RunPost(params struct {
|
||||
IsNotifying bool
|
||||
}) {
|
||||
timeout := time.NewTimer(55 * time.Second) // 比客户端提前结束,避免在客户端产生一个请求错误
|
||||
|
||||
this.Data["clusters"] = []interface{}{}
|
||||
|
||||
Loop:
|
||||
for {
|
||||
select {
|
||||
case <-this.Request.Context().Done():
|
||||
break Loop
|
||||
case <-timeout.C:
|
||||
break Loop
|
||||
default:
|
||||
// 继续
|
||||
}
|
||||
|
||||
resp, err := this.RPC().NodeClusterRPC().FindAllChangedNodeClusters(this.AdminContext(), &pb.FindAllChangedNodeClustersRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
result := []maps.Map{}
|
||||
for _, cluster := range resp.Clusters {
|
||||
result = append(result, maps.Map{
|
||||
"id": cluster.Id,
|
||||
"name": cluster.Name,
|
||||
})
|
||||
}
|
||||
|
||||
// 从提醒到提醒消失
|
||||
if len(result) == 0 && params.IsNotifying {
|
||||
break
|
||||
}
|
||||
|
||||
this.Data["clusters"] = result
|
||||
if len(result) > 0 {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
resp, err := this.RPC().NodeClusterRPC().FindAllChangedNodeClusters(this.AdminContext(), &pb.FindAllChangedNodeClustersRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
result := []maps.Map{}
|
||||
for _, cluster := range resp.Clusters {
|
||||
result = append(result, maps.Map{
|
||||
"id": cluster.Id,
|
||||
"name": cluster.Name,
|
||||
})
|
||||
}
|
||||
|
||||
this.Data["clusters"] = result
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -19,10 +19,17 @@ func (this *SelectPopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *SelectPopupAction) RunGet(params struct{}) {
|
||||
func (this *SelectPopupAction) RunGet(params struct {
|
||||
ViewSize string
|
||||
}) {
|
||||
// TODO 支持关键词搜索
|
||||
// TODO 列出常用的证书供用户选择
|
||||
|
||||
if len(params.ViewSize) == 0 {
|
||||
params.ViewSize = "normal"
|
||||
}
|
||||
this.Data["viewSize"] = params.ViewSize
|
||||
|
||||
countResp, err := this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package settings
|
||||
|
||||
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
@@ -11,5 +13,5 @@ func (this *IndexAction) Init() {
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct{}) {
|
||||
this.Show()
|
||||
this.RedirectURL("/settings/ui")
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/settingutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
)
|
||||
@@ -11,7 +10,6 @@ func init() {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth()).
|
||||
Helper(NewHelper()).
|
||||
Helper(settingutils.NewHelper("console")).
|
||||
Prefix("/settings").
|
||||
Get("", new(IndexAction)).
|
||||
EndAll()
|
||||
|
||||
@@ -25,7 +25,7 @@ func (this *Helper) BeforeAction(actionPtr actions.ActionWrapper) (goNext bool)
|
||||
|
||||
// 标签栏
|
||||
tabbar := actionutils.NewTabbar()
|
||||
tabbar.Add("管理界面", "", "/settings", "", this.tab == "console")
|
||||
tabbar.Add("管理界面", "", "/settings", "", this.tab == "ui")
|
||||
tabbar.Add("安全设置", "", "/settings/security", "", this.tab == "security")
|
||||
tabbar.Add("数据库", "", "/settings/database", "", this.tab == "database")
|
||||
tabbar.Add("API节点", "", "/api", "", this.tab == "apiNodes")
|
||||
|
||||
27
internal/web/actions/default/settings/ui/index.go
Normal file
27
internal/web/actions/default/settings/ui/index.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct{}) {
|
||||
this.Data["serverIsChanged"] = serverConfigIsChanged
|
||||
|
||||
serverConfig, err := loadServerConfig()
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["serverConfig"] = serverConfig
|
||||
|
||||
this.Show()
|
||||
}
|
||||
20
internal/web/actions/default/settings/ui/init.go
Normal file
20
internal/web/actions/default/settings/ui/init.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"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()).
|
||||
Helper(settingutils.NewHelper("ui")).
|
||||
Prefix("/settings/ui").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/updateHTTPPopup", new(UpdateHTTPPopupAction)).
|
||||
GetPost("/updateHTTPSPopup", new(UpdateHTTPSPopupAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
65
internal/web/actions/default/settings/ui/updateHTTPPopup.go
Normal file
65
internal/web/actions/default/settings/ui/updateHTTPPopup.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"net"
|
||||
)
|
||||
|
||||
type UpdateHTTPPopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *UpdateHTTPPopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *UpdateHTTPPopupAction) RunGet(params struct{}) {
|
||||
serverConfig, err := loadServerConfig()
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["serverConfig"] = serverConfig
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *UpdateHTTPPopupAction) RunPost(params struct {
|
||||
IsOn bool
|
||||
Listens []string
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
if len(params.Listens) == 0 {
|
||||
this.Fail("请输入绑定地址")
|
||||
}
|
||||
|
||||
serverConfig, err := loadServerConfig()
|
||||
if err != nil {
|
||||
this.Fail("保存失败:" + err.Error())
|
||||
}
|
||||
|
||||
serverConfig.Http.On = params.IsOn
|
||||
|
||||
listen := []string{}
|
||||
for _, addr := range params.Listens {
|
||||
addr = utils.FormatAddress(addr)
|
||||
if len(addr) == 0 {
|
||||
continue
|
||||
}
|
||||
if _, _, err := net.SplitHostPort(addr); err != nil {
|
||||
addr += ":80"
|
||||
}
|
||||
listen = append(listen, addr)
|
||||
}
|
||||
serverConfig.Http.Listen = listen
|
||||
|
||||
err = writeServerConfig(serverConfig)
|
||||
if err != nil {
|
||||
this.Fail("保存失败:" + err.Error())
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
140
internal/web/actions/default/settings/ui/updateHTTPSPopup.go
Normal file
140
internal/web/actions/default/settings/ui/updateHTTPSPopup.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
)
|
||||
|
||||
type UpdateHTTPSPopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *UpdateHTTPSPopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *UpdateHTTPSPopupAction) RunGet(params struct{}) {
|
||||
serverConfig, err := loadServerConfig()
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["serverConfig"] = serverConfig
|
||||
|
||||
// 证书
|
||||
certConfigs := []*sslconfigs.SSLCertConfig{}
|
||||
if len(serverConfig.Https.Cert) > 0 && len(serverConfig.Https.Key) > 0 {
|
||||
certData, err := ioutil.ReadFile(Tea.Root + "/" + serverConfig.Https.Cert)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
keyData, err := ioutil.ReadFile(Tea.Root + "/" + serverConfig.Https.Key)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
certConfig := &sslconfigs.SSLCertConfig{
|
||||
Id: 0,
|
||||
Name: "-",
|
||||
CertData: certData,
|
||||
KeyData: keyData,
|
||||
}
|
||||
_ = certConfig.Init()
|
||||
certConfig.CertData = nil
|
||||
certConfig.KeyData = nil
|
||||
certConfigs = append(certConfigs, certConfig)
|
||||
}
|
||||
this.Data["certConfigs"] = certConfigs
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *UpdateHTTPSPopupAction) RunPost(params struct {
|
||||
IsOn bool
|
||||
Listens []string
|
||||
CertIdsJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
if len(params.Listens) == 0 {
|
||||
this.Fail("请输入绑定地址")
|
||||
}
|
||||
|
||||
serverConfig, err := loadServerConfig()
|
||||
if err != nil {
|
||||
this.Fail("保存失败:" + err.Error())
|
||||
}
|
||||
|
||||
serverConfig.Https.On = params.IsOn
|
||||
|
||||
listen := []string{}
|
||||
for _, addr := range params.Listens {
|
||||
addr = utils.FormatAddress(addr)
|
||||
if len(addr) == 0 {
|
||||
continue
|
||||
}
|
||||
if _, _, err := net.SplitHostPort(addr); err != nil {
|
||||
addr += ":80"
|
||||
}
|
||||
listen = append(listen, addr)
|
||||
}
|
||||
serverConfig.Https.Listen = listen
|
||||
|
||||
// 证书
|
||||
certIds := []int64{}
|
||||
err = json.Unmarshal(params.CertIdsJSON, &certIds)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if params.IsOn && len(certIds) == 0 {
|
||||
this.Fail("要启用HTTPS,需要先选择或上传一个可用的证书")
|
||||
}
|
||||
|
||||
// 保存证书到本地
|
||||
if len(certIds) > 0 && certIds[0] != 0 {
|
||||
certResp, err := this.RPC().SSLCertRPC().FindEnabledSSLCertConfig(this.AdminContext(), &pb.FindEnabledSSLCertConfigRequest{
|
||||
CertId: certIds[0],
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if len(certResp.CertJSON) == 0 {
|
||||
this.Fail("选择的证书已失效,请换一个")
|
||||
}
|
||||
|
||||
certConfig := &sslconfigs.SSLCertConfig{}
|
||||
err = json.Unmarshal(certResp.CertJSON, certConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
err = ioutil.WriteFile(Tea.ConfigFile("https.key.pem"), certConfig.KeyData, 0666)
|
||||
if err != nil {
|
||||
this.Fail("保存密钥失败:" + err.Error())
|
||||
}
|
||||
err = ioutil.WriteFile(Tea.ConfigFile("https.cert.pem"), certConfig.CertData, 0666)
|
||||
if err != nil {
|
||||
this.Fail("保存证书失败:" + err.Error())
|
||||
}
|
||||
|
||||
serverConfig.Https.Key = "configs/https.key.pem"
|
||||
serverConfig.Https.Cert = "configs/https.cert.pem"
|
||||
}
|
||||
|
||||
err = writeServerConfig(serverConfig)
|
||||
if err != nil {
|
||||
this.Fail("保存配置失败:" + err.Error())
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
41
internal/web/actions/default/settings/ui/utils.go
Normal file
41
internal/web/actions/default/settings/ui/utils.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"github.com/iwind/TeaGo"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
var serverConfigIsChanged = false
|
||||
|
||||
// 读取当前服务配置
|
||||
func loadServerConfig() (*TeaGo.ServerConfig, error) {
|
||||
configFile := Tea.ConfigFile("server.yaml")
|
||||
data, err := ioutil.ReadFile(configFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
serverConfig := &TeaGo.ServerConfig{}
|
||||
err = yaml.Unmarshal(data, serverConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return serverConfig, nil
|
||||
}
|
||||
|
||||
// 保存当前服务配置
|
||||
func writeServerConfig(serverConfig *TeaGo.ServerConfig) error {
|
||||
data, err := yaml.Marshal(serverConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(Tea.ConfigFile("server.yaml"), data, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serverConfigIsChanged = true
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user