Compare commits
104 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ff8aecbea | ||
|
|
e6cae84764 | ||
|
|
2d2d2931f1 | ||
|
|
69ad5e7d1f | ||
|
|
97abc6aeb9 | ||
|
|
8cf37dd37c | ||
|
|
e11d091ac5 | ||
|
|
e952dfcedd | ||
|
|
2565d5cab2 | ||
|
|
e4e66c74bc | ||
|
|
6607c41823 | ||
|
|
43570f20b5 | ||
|
|
9ea7a93206 | ||
|
|
dec4922fe5 | ||
|
|
ef1f95b347 | ||
|
|
7317312f68 | ||
|
|
2965e8df65 | ||
|
|
4fdcc7fae9 | ||
|
|
6be8f7539d | ||
|
|
a6de65fe39 | ||
|
|
fc5dae5a8e | ||
|
|
db69454d32 | ||
|
|
c824335b0e | ||
|
|
1f1ce11078 | ||
|
|
0ec1571d37 | ||
|
|
407e8b52a5 | ||
|
|
1be13a151d | ||
|
|
4d9d417d7a | ||
|
|
aaff8f0c4a | ||
|
|
8c064daf3f | ||
|
|
b0b3dae147 | ||
|
|
2ea2be43d3 | ||
|
|
81f7364e93 | ||
|
|
c530869530 | ||
|
|
586ccd90ec | ||
|
|
ece237c49f | ||
|
|
11da5ca98c | ||
|
|
276a68bda6 | ||
|
|
fba89d197a | ||
|
|
b3259e2489 | ||
|
|
880704dda0 | ||
|
|
d5e92e9c09 | ||
|
|
df2f5692bd | ||
|
|
dacc99b8b6 | ||
|
|
0e8ade3b61 | ||
|
|
fe2d8f6261 | ||
|
|
927381039b | ||
|
|
6b95947acb | ||
|
|
b05e53ce58 | ||
|
|
a2546582f2 | ||
|
|
a023b3401e | ||
|
|
07142e9872 | ||
|
|
f5fea6c34d | ||
|
|
5eb0fb3422 | ||
|
|
fa915e7c35 | ||
|
|
2b7905d31c | ||
|
|
9cbbf37add | ||
|
|
642a0c3b0d | ||
|
|
ff47a19250 | ||
|
|
1fc1a3fbe3 | ||
|
|
996172bd69 | ||
|
|
df038314ef | ||
|
|
67881c2e34 | ||
|
|
9c691a17b2 | ||
|
|
54df86a4a2 | ||
|
|
70aff759d7 | ||
|
|
d903cc6e3b | ||
|
|
c520271ab5 | ||
|
|
f6936224d9 | ||
|
|
283984a6a6 | ||
|
|
c4fc09f72a | ||
|
|
efdbabfa04 | ||
|
|
a43af333fd | ||
|
|
1f5894ff82 | ||
|
|
79b4054e31 | ||
|
|
376d7d0c78 | ||
|
|
c8b85330ed | ||
|
|
c65dffee13 | ||
|
|
275320ad9b | ||
|
|
f71cdf9065 | ||
|
|
8e0a239de9 | ||
|
|
ed2b95bc3f | ||
|
|
2e23ee4c66 | ||
|
|
58def52e30 | ||
|
|
aea5ef3b68 | ||
|
|
f2e14cf0a6 | ||
|
|
bc9b6d1595 | ||
|
|
fd11b62390 | ||
|
|
8db00a5ab5 | ||
|
|
a6757e9374 | ||
|
|
e0fe385404 | ||
|
|
f9f4258ec1 | ||
|
|
f939d563ad | ||
|
|
fad03add54 | ||
|
|
9ab6dab081 | ||
|
|
5a55268830 | ||
|
|
fc3769239d | ||
|
|
c9fb3153eb | ||
|
|
a31f9ed9c5 | ||
|
|
2f75828ba4 | ||
|
|
89679ec358 | ||
|
|
98f77f52df | ||
|
|
ca647d44bb | ||
|
|
838b7dab5b |
@@ -54,7 +54,7 @@
|
|||||||
* [管理平台](https://github.com/TeaOSLab/EdgeAdmin)
|
* [管理平台](https://github.com/TeaOSLab/EdgeAdmin)
|
||||||
|
|
||||||
## 联系我们
|
## 联系我们
|
||||||
有什么问题和建议都可以加入QQ群 `659832182` 或者 [Telegram群](https://t.me/+5kVCMGxQhZxiODY9) 。
|
有什么问题和建议都可以加入 [Telegram群](https://t.me/+5kVCMGxQhZxiODY9)
|
||||||
|
|
||||||
## 企业版
|
## 企业版
|
||||||
* [GoEdge企业版](https://goedge.cn/commercial) - 功能更强大的CDN系统
|
* [GoEdge企业版](https://goedge.cn/commercial) - 功能更强大的CDN系统
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
这个目录下我们列举了所有需要公开声明的第三方License,如果有遗漏,烦请告知 iwind.liu@gmail.com。再次感谢这些开源软件项目和贡献人员!
|
这个目录下我们列举了所有需要公开声明的第三方License,如果有遗漏,烦请告知 goedge.cdn@gmail.com。再次感谢这些开源软件项目和贡献人员!
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
LABEL maintainer="iwind.liu@gmail.com"
|
LABEL maintainer="goedge.cdn@gmail.com"
|
||||||
ENV TZ "Asia/Shanghai"
|
ENV TZ "Asia/Shanghai"
|
||||||
ENV VERSION 0.6.4.2
|
ENV VERSION 1.1.0
|
||||||
ENV ROOT_DIR /usr/local/goedge
|
ENV ROOT_DIR /usr/local/goedge
|
||||||
ENV TAR_FILE edge-admin-linux-amd64-plus-v${VERSION}.zip
|
ENV TAR_FILE edge-admin-linux-amd64-plus-v${VERSION}.zip
|
||||||
ENV TAR_URL "https://dl.goedge.cn/edge/v${VERSION}/edge-admin-linux-amd64-plus-v${VERSION}.zip"
|
ENV TAR_URL "https://dl.goedge.cn/edge/v${VERSION}/edge-admin-linux-amd64-plus-v${VERSION}.zip"
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ func AllModuleMaps() []maps.Map {
|
|||||||
"url": "/dashboard",
|
"url": "/dashboard",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "网站服务",
|
"name": "网站列表",
|
||||||
"code": AdminModuleCodeServer,
|
"code": AdminModuleCodeServer,
|
||||||
"url": "/servers",
|
"url": "/servers",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func LoadSecurityConfig() (*systemconfigs.SecurityConfig, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
v := reflect.Indirect(reflect.ValueOf(config)).Interface().(systemconfigs.SecurityConfig)
|
var v = reflect.Indirect(reflect.ValueOf(config)).Interface().(systemconfigs.SecurityConfig)
|
||||||
return &v, nil
|
return &v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,12 @@ func loadSecurityConfig() (*systemconfigs.SecurityConfig, error) {
|
|||||||
return sharedSecurityConfig, nil
|
return sharedSecurityConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &systemconfigs.SecurityConfig{}
|
var config = &systemconfigs.SecurityConfig{
|
||||||
|
Frame: FrameSameOrigin,
|
||||||
|
AllowLocal: true,
|
||||||
|
CheckClientFingerprint: false,
|
||||||
|
CheckClientRegion: true,
|
||||||
|
}
|
||||||
err = json.Unmarshal(resp.ValueJSON, config)
|
err = json.Unmarshal(resp.ValueJSON, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Println("[SECURITY_MANAGER]" + err.Error())
|
logs.Println("[SECURITY_MANAGER]" + err.Error())
|
||||||
@@ -100,7 +105,9 @@ func loadSecurityConfig() (*systemconfigs.SecurityConfig, error) {
|
|||||||
|
|
||||||
func defaultSecurityConfig() *systemconfigs.SecurityConfig {
|
func defaultSecurityConfig() *systemconfigs.SecurityConfig {
|
||||||
return &systemconfigs.SecurityConfig{
|
return &systemconfigs.SecurityConfig{
|
||||||
Frame: FrameSameOrigin,
|
Frame: FrameSameOrigin,
|
||||||
AllowLocal: true,
|
AllowLocal: true,
|
||||||
|
CheckClientFingerprint: false,
|
||||||
|
CheckClientRegion: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package teaconst
|
package teaconst
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "1.0.0"
|
Version = "1.2.0"
|
||||||
|
|
||||||
APINodeVersion = "1.0.0"
|
APINodeVersion = "1.2.0"
|
||||||
|
|
||||||
ProductName = "Edge Admin"
|
ProductName = "Edge Admin"
|
||||||
ProcessName = "edge-admin"
|
ProcessName = "edge-admin"
|
||||||
|
|||||||
@@ -85,6 +85,9 @@ func (this *AdminNode) Run() {
|
|||||||
// 启动API节点
|
// 启动API节点
|
||||||
this.startAPINode()
|
this.startAPINode()
|
||||||
|
|
||||||
|
// 启动IP库
|
||||||
|
this.startIPLibrary()
|
||||||
|
|
||||||
// 启动Web服务
|
// 启动Web服务
|
||||||
sessionManager, err := NewSessionManager()
|
sessionManager, err := NewSessionManager()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
18
internal/nodes/admin_node_ext.go
Normal file
18
internal/nodes/admin_node_ext.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package nodes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||||
|
"github.com/iwind/TeaGo/logs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 启动IP库
|
||||||
|
func (this *AdminNode) startIPLibrary() {
|
||||||
|
logs.Println("[NODE]initializing ip library ...")
|
||||||
|
err := iplibrary.InitDefault()
|
||||||
|
if err != nil {
|
||||||
|
logs.Println("[NODE]initialize ip library failed: "+err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ func (this *SessionManager) Read(sid string) map[string]string {
|
|||||||
resp, err := rpcClient.LoginSessionRPC().FindLoginSession(rpcClient.Context(0), &pb.FindLoginSessionRequest{Sid: sid})
|
resp, err := rpcClient.LoginSessionRPC().FindLoginSession(rpcClient.Context(0), &pb.FindLoginSessionRequest{Sid: sid})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Println("SESSION", "read '"+sid+"' failed: "+err.Error())
|
logs.Println("SESSION", "read '"+sid+"' failed: "+err.Error())
|
||||||
|
result["@error"] = err.Error()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package rpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/configs"
|
"github.com/TeaOSLab/EdgeAdmin/internal/configs"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -28,3 +31,39 @@ func SharedRPC() (*RPCClient, error) {
|
|||||||
sharedRPC = client
|
sharedRPC = client
|
||||||
return sharedRPC, nil
|
return sharedRPC, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsConnError 是否为连接错误
|
||||||
|
func IsConnError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否为连接错误
|
||||||
|
statusErr, ok := status.FromError(err)
|
||||||
|
if ok {
|
||||||
|
var errorCode = statusErr.Code()
|
||||||
|
return errorCode == codes.Unavailable || errorCode == codes.Canceled
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(err.Error(), "code = Canceled") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsUnimplementedError 检查是否为未实现错误
|
||||||
|
func IsUnimplementedError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
statusErr, ok := status.FromError(err)
|
||||||
|
if ok {
|
||||||
|
if statusErr.Code() == codes.Unimplemented {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ func (this *CheckUpdatesTask) Loop() error {
|
|||||||
var vMap = maps.NewMap(version)
|
var vMap = maps.NewMap(version)
|
||||||
if vMap.GetString("code") == "admin" {
|
if vMap.GetString("code") == "admin" {
|
||||||
var latestVersion = vMap.GetString("version")
|
var latestVersion = vMap.GetString("version")
|
||||||
if stringutil.VersionCompare(teaconst.Version, latestVersion) < 0 {
|
if stringutil.VersionCompare(teaconst.Version, latestVersion) < 0 && (len(config.IgnoredVersion) == 0 || stringutil.VersionCompare(latestVersion, config.IgnoredVersion) > 0) {
|
||||||
teaconst.NewVersionCode = latestVersion
|
teaconst.NewVersionCode = latestVersion
|
||||||
teaconst.NewVersionDownloadURL = dlHost + vMap.GetString("url")
|
teaconst.NewVersionDownloadURL = dlHost + vMap.GetString("url")
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
79
internal/utils/apinodeutils/deploy_file.go
Normal file
79
internal/utils/apinodeutils/deploy_file.go
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package apinodeutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeployFile 部署文件描述
|
||||||
|
type DeployFile struct {
|
||||||
|
OS string
|
||||||
|
Arch string
|
||||||
|
Version string
|
||||||
|
Path string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum 计算概要
|
||||||
|
func (this *DeployFile) Sum() (string, error) {
|
||||||
|
fp, err := os.Open(this.Path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = fp.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
m := md5.New()
|
||||||
|
buffer := make([]byte, 128*1024)
|
||||||
|
for {
|
||||||
|
n, err := fp.Read(buffer)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
_, err = m.Write(buffer[:n])
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum := m.Sum(nil)
|
||||||
|
return fmt.Sprintf("%x", sum), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read 读取一个片段数据
|
||||||
|
func (this *DeployFile) Read(offset int64) (data []byte, newOffset int64, err error) {
|
||||||
|
fp, err := os.Open(this.Path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, offset, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = fp.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
stat, err := fp.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return nil, offset, err
|
||||||
|
}
|
||||||
|
if offset >= stat.Size() {
|
||||||
|
return nil, offset, io.EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fp.Seek(offset, io.SeekStart)
|
||||||
|
if err != nil {
|
||||||
|
return nil, offset, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer := make([]byte, 128*1024)
|
||||||
|
n, err := fp.Read(buffer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, offset, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer[:n], offset + int64(n), nil
|
||||||
|
}
|
||||||
96
internal/utils/apinodeutils/deploy_manager.go
Normal file
96
internal/utils/apinodeutils/deploy_manager.go
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package apinodeutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
|
"github.com/iwind/TeaGo/files"
|
||||||
|
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeployManager 节点部署文件管理器
|
||||||
|
// 如果节点部署文件有变化,需要重启API节点以便于生效
|
||||||
|
type DeployManager struct {
|
||||||
|
dir string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDeployManager 获取新节点部署文件管理器
|
||||||
|
func NewDeployManager() *DeployManager {
|
||||||
|
var manager = &DeployManager{
|
||||||
|
dir: Tea.Root + "/edge-api/deploy",
|
||||||
|
}
|
||||||
|
manager.LoadNodeFiles()
|
||||||
|
manager.LoadNSNodeFiles()
|
||||||
|
return manager
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadNodeFiles 加载所有边缘节点文件
|
||||||
|
func (this *DeployManager) LoadNodeFiles() []*DeployFile {
|
||||||
|
var keyMap = map[string]*DeployFile{} // key => File
|
||||||
|
|
||||||
|
var reg = regexp.MustCompile(`^edge-node-(\w+)-(\w+)-v([0-9.]+)\.zip$`)
|
||||||
|
for _, file := range files.NewFile(this.dir).List() {
|
||||||
|
var name = file.Name()
|
||||||
|
if !reg.MatchString(name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var matches = reg.FindStringSubmatch(name)
|
||||||
|
var osName = matches[1]
|
||||||
|
var arch = matches[2]
|
||||||
|
var version = matches[3]
|
||||||
|
|
||||||
|
var key = osName + "_" + arch
|
||||||
|
oldFile, ok := keyMap[key]
|
||||||
|
if ok && stringutil.VersionCompare(oldFile.Version, version) > 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
keyMap[key] = &DeployFile{
|
||||||
|
OS: osName,
|
||||||
|
Arch: arch,
|
||||||
|
Version: version,
|
||||||
|
Path: file.Path(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = []*DeployFile{}
|
||||||
|
for _, v := range keyMap {
|
||||||
|
result = append(result, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadNSNodeFiles 加载所有NS节点安装文件
|
||||||
|
func (this *DeployManager) LoadNSNodeFiles() []*DeployFile {
|
||||||
|
var keyMap = map[string]*DeployFile{} // key => File
|
||||||
|
|
||||||
|
var reg = regexp.MustCompile(`^edge-dns-(\w+)-(\w+)-v([0-9.]+)\.zip$`)
|
||||||
|
for _, file := range files.NewFile(this.dir).List() {
|
||||||
|
var name = file.Name()
|
||||||
|
if !reg.MatchString(name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var matches = reg.FindStringSubmatch(name)
|
||||||
|
var osName = matches[1]
|
||||||
|
var arch = matches[2]
|
||||||
|
var version = matches[3]
|
||||||
|
|
||||||
|
var key = osName + "_" + arch
|
||||||
|
oldFile, ok := keyMap[key]
|
||||||
|
if ok && stringutil.VersionCompare(oldFile.Version, version) > 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
keyMap[key] = &DeployFile{
|
||||||
|
OS: osName,
|
||||||
|
Arch: arch,
|
||||||
|
Version: version,
|
||||||
|
Path: file.Path(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = []*DeployFile{}
|
||||||
|
for _, v := range keyMap {
|
||||||
|
result = append(result, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ package apinodeutils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
|
"context"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -62,7 +63,36 @@ func (this *Upgrader) Upgrade() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
versionResp, err := rpcClient.APINodeRPC().FindCurrentAPINodeVersion(sharedClient.Context(0), &pb.FindCurrentAPINodeVersionRequest{})
|
|
||||||
|
// 升级边缘节点
|
||||||
|
err = this.upgradeNodes(sharedClient.Context(0), rpcClient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 升级NS节点
|
||||||
|
err = this.upgradeNSNodes(sharedClient.Context(0), rpcClient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 升级API节点
|
||||||
|
err = this.upgradeAPINode(sharedClient.Context(0), rpcClient)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("upgrade api node failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Progress 查看升级进程
|
||||||
|
func (this *Upgrader) Progress() *Progress {
|
||||||
|
return this.progress
|
||||||
|
}
|
||||||
|
|
||||||
|
// 升级API节点
|
||||||
|
func (this *Upgrader) upgradeAPINode(ctx context.Context, rpcClient *rpc.RPCClient) error {
|
||||||
|
versionResp, err := rpcClient.APINodeRPC().FindCurrentAPINodeVersion(ctx, &pb.FindCurrentAPINodeVersionRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -77,7 +107,7 @@ func (this *Upgrader) Upgrade() error {
|
|||||||
return errors.New(reason)
|
return errors.New(reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
localVersion, err := localVersion()
|
localVersion, err := lookupLocalVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("lookup version failed: " + err.Error())
|
return errors.New("lookup version failed: " + err.Error())
|
||||||
}
|
}
|
||||||
@@ -196,6 +226,124 @@ func (this *Upgrader) Upgrade() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Upgrader) Progress() *Progress {
|
// 升级边缘节点
|
||||||
return this.progress
|
func (this *Upgrader) upgradeNodes(ctx context.Context, rpcClient *rpc.RPCClient) error {
|
||||||
|
// 本地的
|
||||||
|
var manager = NewDeployManager()
|
||||||
|
var localFileMap = map[string]*DeployFile{} // os_arch => *DeployFile
|
||||||
|
for _, deployFile := range manager.LoadNodeFiles() {
|
||||||
|
localFileMap[deployFile.OS+"_"+deployFile.Arch] = deployFile
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteFilesResp, err := rpcClient.APINodeRPC().FindLatestDeployFiles(ctx, &pb.FindLatestDeployFilesRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var remoteFileMap = map[string]*pb.FindLatestDeployFilesResponse_DeployFile{} // os_arch => *DeployFile
|
||||||
|
for _, nodeFile := range remoteFilesResp.NodeDeployFiles {
|
||||||
|
remoteFileMap[nodeFile.Os+"_"+nodeFile.Arch] = nodeFile
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对比版本
|
||||||
|
for key, deployFile := range localFileMap {
|
||||||
|
remoteDeployFile, ok := remoteFileMap[key]
|
||||||
|
if !ok || stringutil.VersionCompare(remoteDeployFile.Version, deployFile.Version) < 0 {
|
||||||
|
err = this.uploadNodeDeployFile(ctx, rpcClient, deployFile.Path)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("upload deploy file '" + filepath.Base(deployFile.Path) + "' failed: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 升级NS节点
|
||||||
|
func (this *Upgrader) upgradeNSNodes(ctx context.Context, rpcClient *rpc.RPCClient) error {
|
||||||
|
// 本地的
|
||||||
|
var manager = NewDeployManager()
|
||||||
|
var localFileMap = map[string]*DeployFile{} // os_arch => *DeployFile
|
||||||
|
for _, deployFile := range manager.LoadNSNodeFiles() {
|
||||||
|
localFileMap[deployFile.OS+"_"+deployFile.Arch] = deployFile
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteFilesResp, err := rpcClient.APINodeRPC().FindLatestDeployFiles(ctx, &pb.FindLatestDeployFilesRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var remoteFileMap = map[string]*pb.FindLatestDeployFilesResponse_DeployFile{} // os_arch => *DeployFile
|
||||||
|
for _, nodeFile := range remoteFilesResp.NsNodeDeployFiles {
|
||||||
|
remoteFileMap[nodeFile.Os+"_"+nodeFile.Arch] = nodeFile
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对比版本
|
||||||
|
for key, deployFile := range localFileMap {
|
||||||
|
remoteDeployFile, ok := remoteFileMap[key]
|
||||||
|
if !ok || stringutil.VersionCompare(remoteDeployFile.Version, deployFile.Version) < 0 {
|
||||||
|
err = this.uploadNodeDeployFile(ctx, rpcClient, deployFile.Path)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("upload deploy file '" + filepath.Base(deployFile.Path) + "' failed: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传节点文件
|
||||||
|
func (this *Upgrader) uploadNodeDeployFile(ctx context.Context, rpcClient *rpc.RPCClient, path string) error {
|
||||||
|
fp, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = fp.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
var buf = make([]byte, 128*4096)
|
||||||
|
var isFirst = true
|
||||||
|
|
||||||
|
var hash = md5.New()
|
||||||
|
|
||||||
|
for {
|
||||||
|
n, err := fp.Read(buf)
|
||||||
|
if n > 0 {
|
||||||
|
hash.Write(buf[:n])
|
||||||
|
|
||||||
|
_, uploadErr := rpcClient.APINodeRPC().UploadDeployFileToAPINode(ctx, &pb.UploadDeployFileToAPINodeRequest{
|
||||||
|
Filename: filepath.Base(path),
|
||||||
|
Sum: "",
|
||||||
|
ChunkData: buf[:n],
|
||||||
|
IsFirstChunk: isFirst,
|
||||||
|
IsLastChunk: false,
|
||||||
|
})
|
||||||
|
if uploadErr != nil {
|
||||||
|
return uploadErr
|
||||||
|
}
|
||||||
|
isFirst = false
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
err = nil
|
||||||
|
|
||||||
|
_, uploadErr := rpcClient.APINodeRPC().UploadDeployFileToAPINode(ctx, &pb.UploadDeployFileToAPINodeRequest{
|
||||||
|
Filename: filepath.Base(path),
|
||||||
|
Sum: fmt.Sprintf("%x", hash.Sum(nil)),
|
||||||
|
ChunkData: nil,
|
||||||
|
IsFirstChunk: false,
|
||||||
|
IsLastChunk: true,
|
||||||
|
})
|
||||||
|
if uploadErr != nil {
|
||||||
|
return uploadErr
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func CanUpgrade(apiVersion string, osName string, arch string) (canUpgrade bool,
|
|||||||
return false, "is directory"
|
return false, "is directory"
|
||||||
}
|
}
|
||||||
|
|
||||||
localVersion, err := localVersion()
|
localVersion, err := lookupLocalVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, "lookup version failed: " + err.Error()
|
return false, "lookup version failed: " + err.Error()
|
||||||
}
|
}
|
||||||
@@ -53,9 +53,7 @@ func CanUpgrade(apiVersion string, osName string, arch string) (canUpgrade bool,
|
|||||||
return true, ""
|
return true, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func lookupLocalVersion() (string, error) {
|
||||||
|
|
||||||
func localVersion() (string, error) {
|
|
||||||
var cmd = exec.Command(apiExe(), "-V")
|
var cmd = exec.Command(apiExe(), "-V")
|
||||||
var output = &bytes.Buffer{}
|
var output = &bytes.Buffer{}
|
||||||
cmd.Stdout = output
|
cmd.Stdout = output
|
||||||
@@ -74,7 +72,6 @@ func localVersion() (string, error) {
|
|||||||
return localVersion, nil
|
return localVersion, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func apiExe() string {
|
func apiExe() string {
|
||||||
return Tea.Root + "/edge-api/bin/edge-api"
|
return Tea.Root + "/edge-api/bin/edge-api"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ func FormatCount(count int64) string {
|
|||||||
return fmt.Sprintf("%.1fB", float32(count)/1000/1000/1000)
|
return fmt.Sprintf("%.1fB", float32(count)/1000/1000/1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FormatFloat(f interface{}, decimal int) string {
|
func FormatFloat(f any, decimal int) string {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -101,10 +101,29 @@ func FormatFloat(f interface{}, decimal int) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func FormatFloat2(f interface{}) string {
|
func FormatFloat2(f any) string {
|
||||||
return FormatFloat(f, 2)
|
return FormatFloat(f, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PadFloatZero 为浮点型数字字符串填充足够的0
|
||||||
|
func PadFloatZero(s string, countZero int) string {
|
||||||
|
if countZero <= 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
if len(s) == 0 {
|
||||||
|
s = "0"
|
||||||
|
}
|
||||||
|
var index = strings.Index(s, ".")
|
||||||
|
if index < 0 {
|
||||||
|
return s + "." + strings.Repeat("0", countZero)
|
||||||
|
}
|
||||||
|
var decimalLen = len(s) - 1 - index
|
||||||
|
if decimalLen < countZero {
|
||||||
|
return s + strings.Repeat("0", countZero-decimalLen)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
var decimalReg = regexp.MustCompile(`^(\d+\.\d+)([a-zA-Z]+)?$`)
|
var decimalReg = regexp.MustCompile(`^(\d+\.\d+)([a-zA-Z]+)?$`)
|
||||||
|
|
||||||
// TrimZeroSuffix 去除小数数字尾部多余的0
|
// TrimZeroSuffix 去除小数数字尾部多余的0
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package numberutils_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||||
|
"github.com/iwind/TeaGo/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,6 +50,24 @@ func TestFormatFloat(t *testing.T) {
|
|||||||
t.Log(numberutils.FormatFloat(-221745.12, 2))
|
t.Log(numberutils.FormatFloat(-221745.12, 2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFormatFloat2(t *testing.T) {
|
||||||
|
t.Log(numberutils.FormatFloat2(0))
|
||||||
|
t.Log(numberutils.FormatFloat2(0.0))
|
||||||
|
t.Log(numberutils.FormatFloat2(1.23456))
|
||||||
|
t.Log(numberutils.FormatFloat2(1.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPadFloatZero(t *testing.T) {
|
||||||
|
var a = assert.NewAssertion(t)
|
||||||
|
a.IsTrue(numberutils.PadFloatZero("1", 0) == "1")
|
||||||
|
a.IsTrue(numberutils.PadFloatZero("1", 2) == "1.00")
|
||||||
|
a.IsTrue(numberutils.PadFloatZero("1.1", 2) == "1.10")
|
||||||
|
a.IsTrue(numberutils.PadFloatZero("1.12", 2) == "1.12")
|
||||||
|
a.IsTrue(numberutils.PadFloatZero("1.123", 2) == "1.123")
|
||||||
|
a.IsTrue(numberutils.PadFloatZero("10000.123", 2) == "10000.123")
|
||||||
|
a.IsTrue(numberutils.PadFloatZero("", 2) == "0.00")
|
||||||
|
}
|
||||||
|
|
||||||
func TestTrimZeroSuffix(t *testing.T) {
|
func TestTrimZeroSuffix(t *testing.T) {
|
||||||
for _, s := range []string{
|
for _, s := range []string{
|
||||||
"1",
|
"1",
|
||||||
|
|||||||
56
internal/utils/taskutils/concurrent.go
Normal file
56
internal/utils/taskutils/concurrent.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package taskutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RunConcurrent(tasks any, concurrent int, f func(task any)) error {
|
||||||
|
if tasks == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var tasksValue = reflect.ValueOf(tasks)
|
||||||
|
if tasksValue.Type().Kind() != reflect.Slice {
|
||||||
|
return errors.New("ony works for slice")
|
||||||
|
}
|
||||||
|
|
||||||
|
var countTasks = tasksValue.Len()
|
||||||
|
if countTasks == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if concurrent <= 0 {
|
||||||
|
concurrent = 8
|
||||||
|
}
|
||||||
|
if concurrent > countTasks {
|
||||||
|
concurrent = countTasks
|
||||||
|
}
|
||||||
|
|
||||||
|
var taskChan = make(chan any, countTasks)
|
||||||
|
for i := 0; i < countTasks; i++ {
|
||||||
|
taskChan <- tasksValue.Index(i).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
var wg = &sync.WaitGroup{}
|
||||||
|
wg.Add(concurrent)
|
||||||
|
for i := 0; i < concurrent; i++ {
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case task := <-taskChan:
|
||||||
|
f(task)
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
17
internal/utils/taskutils/concurrent_test.go
Normal file
17
internal/utils/taskutils/concurrent_test.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package taskutils_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/utils/taskutils"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRunConcurrent(t *testing.T) {
|
||||||
|
err := taskutils.RunConcurrent([]string{"a", "b", "c", "d", "e"}, 3, func(task any) {
|
||||||
|
t.Log("run", task)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,37 +2,49 @@ package actionutils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/iwind/TeaGo/actions"
|
"github.com/iwind/TeaGo/actions"
|
||||||
"github.com/iwind/TeaGo/maps"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type TabItem struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
SubName string `json:"subName"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Icon string `json:"icon"`
|
||||||
|
IsActive bool `json:"isActive"`
|
||||||
|
IsRight bool `json:"isRight"`
|
||||||
|
IsTitle bool `json:"isTitle"`
|
||||||
|
IsDisabled bool `json:"isDisabled"`
|
||||||
|
}
|
||||||
|
|
||||||
// Tabbar Tabbar定义
|
// Tabbar Tabbar定义
|
||||||
type Tabbar struct {
|
type Tabbar struct {
|
||||||
items []maps.Map
|
items []*TabItem
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTabbar 获取新对象
|
// NewTabbar 获取新对象
|
||||||
func NewTabbar() *Tabbar {
|
func NewTabbar() *Tabbar {
|
||||||
return &Tabbar{
|
return &Tabbar{
|
||||||
items: []maps.Map{},
|
items: []*TabItem{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add 添加菜单项
|
// Add 添加菜单项
|
||||||
func (this *Tabbar) Add(name string, subName string, url string, icon string, active bool) maps.Map {
|
func (this *Tabbar) Add(name string, subName string, url string, icon string, active bool) *TabItem {
|
||||||
m := maps.Map{
|
var m = &TabItem{
|
||||||
"name": name,
|
Name: name,
|
||||||
"subName": subName,
|
SubName: subName,
|
||||||
"url": url,
|
URL: url,
|
||||||
"icon": icon,
|
Icon: icon,
|
||||||
"active": active,
|
IsActive: active,
|
||||||
"right": false,
|
IsRight: false,
|
||||||
|
IsTitle: false,
|
||||||
|
IsDisabled: false,
|
||||||
}
|
}
|
||||||
this.items = append(this.items, m)
|
this.items = append(this.items, m)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
// Items 取得所有的Items
|
// Items 取得所有的Items
|
||||||
func (this *Tabbar) Items() []maps.Map {
|
func (this *Tabbar) Items() []*TabItem {
|
||||||
return this.items
|
return this.items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,10 +24,19 @@ import (
|
|||||||
|
|
||||||
// Fail 提示服务器错误信息
|
// Fail 提示服务器错误信息
|
||||||
func Fail(action actions.ActionWrapper, err error) {
|
func Fail(action actions.ActionWrapper, err error) {
|
||||||
if err != nil {
|
if err == nil {
|
||||||
logs.Println("[" + reflect.TypeOf(action).String() + "]" + findStack(err.Error()))
|
err = errors.New("unknown error")
|
||||||
}
|
}
|
||||||
action.Object().Fail(teaconst.ErrServer + "(" + err.Error() + ")")
|
|
||||||
|
logs.Println("[" + reflect.TypeOf(action).String() + "]" + findStack(err.Error()))
|
||||||
|
|
||||||
|
_, _, isLocalAPI, issuesHTML := parseAPIErr(action, err)
|
||||||
|
if isLocalAPI && len(issuesHTML) > 0 {
|
||||||
|
action.Object().Fail(teaconst.ErrServer + "(" + err.Error() + ";最近一次错误提示:" + issuesHTML + ")")
|
||||||
|
} else {
|
||||||
|
action.Object().Fail(teaconst.ErrServer + "(" + err.Error() + ")")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FailPage 提示页面错误信息
|
// FailPage 提示页面错误信息
|
||||||
@@ -38,67 +47,11 @@ func FailPage(action actions.ActionWrapper, err error) {
|
|||||||
|
|
||||||
logs.Println("[" + reflect.TypeOf(action).String() + "]" + findStack(err.Error()))
|
logs.Println("[" + reflect.TypeOf(action).String() + "]" + findStack(err.Error()))
|
||||||
|
|
||||||
// 当前API终端地址
|
|
||||||
var apiEndpoints = []string{}
|
|
||||||
apiConfig, apiConfigErr := configs.LoadAPIConfig()
|
|
||||||
if apiConfigErr == nil && apiConfig != nil {
|
|
||||||
apiEndpoints = append(apiEndpoints, apiConfig.RPC.Endpoints...)
|
|
||||||
}
|
|
||||||
|
|
||||||
var isRPCConnError bool
|
|
||||||
err, isRPCConnError = rpcerrors.HumanError(err, apiEndpoints, Tea.ConfigFile("api.yaml"))
|
|
||||||
var apiNodeIsStarting = false
|
|
||||||
var apiNodeProgress = ""
|
|
||||||
if isRPCConnError {
|
|
||||||
// API节点是否正在启动
|
|
||||||
var sock = gosock.NewTmpSock("edge-api")
|
|
||||||
reply, err := sock.SendTimeout(&gosock.Command{
|
|
||||||
Code: "starting",
|
|
||||||
Params: nil,
|
|
||||||
}, 1*time.Second)
|
|
||||||
if err == nil && reply != nil {
|
|
||||||
var params = maps.NewMap(reply.Params)
|
|
||||||
if params.GetBool("isStarting") {
|
|
||||||
apiNodeIsStarting = true
|
|
||||||
|
|
||||||
var progressMap = params.GetMap("progress")
|
|
||||||
apiNodeProgress = progressMap.GetString("description")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action.Object().ResponseWriter.WriteHeader(http.StatusInternalServerError)
|
action.Object().ResponseWriter.WriteHeader(http.StatusInternalServerError)
|
||||||
if len(action.Object().Request.Header.Get("X-Requested-With")) > 0 {
|
if len(action.Object().Request.Header.Get("X-Requested-With")) > 0 {
|
||||||
action.Object().WriteString(teaconst.ErrServer)
|
action.Object().WriteString(teaconst.ErrServer)
|
||||||
} else {
|
} else {
|
||||||
// 本地的一些错误提示
|
apiNodeIsStarting, apiNodeProgress, _, issuesHTML := parseAPIErr(action, err)
|
||||||
var isLocalAPI = false
|
|
||||||
if isRPCConnError {
|
|
||||||
host, _, hostErr := net.SplitHostPort(action.Object().Request.Host)
|
|
||||||
if hostErr == nil {
|
|
||||||
for _, endpoint := range apiEndpoints {
|
|
||||||
if strings.HasPrefix(endpoint, "http://"+host) || strings.HasPrefix(endpoint, "https://"+host) || strings.HasPrefix(endpoint, host) {
|
|
||||||
isLocalAPI = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var issuesHTML = ""
|
|
||||||
if isLocalAPI {
|
|
||||||
// 读取本地API节点的issues
|
|
||||||
issuesData, issuesErr := os.ReadFile(Tea.Root + "/edge-api/logs/issues.log")
|
|
||||||
if issuesErr == nil {
|
|
||||||
var issueMaps = []maps.Map{}
|
|
||||||
issuesErr = json.Unmarshal(issuesData, &issueMaps)
|
|
||||||
if issuesErr == nil && len(issueMaps) > 0 {
|
|
||||||
var issueMap = issueMaps[0]
|
|
||||||
issuesHTML = "本地API节点启动错误:" + issueMap.GetString("message") + ",处理建议:" + issueMap.GetString("suggestion")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var html = `<!DOCTYPE html>
|
var html = `<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
@@ -187,3 +140,61 @@ func findStack(err string) string {
|
|||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 分析API节点的错误信息
|
||||||
|
func parseAPIErr(action actions.ActionWrapper, err error) (apiNodeIsStarting bool, apiNodeProgress string, isLocalAPI bool, issuesHTML string) {
|
||||||
|
// 当前API终端地址
|
||||||
|
var apiEndpoints = []string{}
|
||||||
|
apiConfig, apiConfigErr := configs.LoadAPIConfig()
|
||||||
|
if apiConfigErr == nil && apiConfig != nil {
|
||||||
|
apiEndpoints = append(apiEndpoints, apiConfig.RPC.Endpoints...)
|
||||||
|
}
|
||||||
|
|
||||||
|
var isRPCConnError bool
|
||||||
|
err, isRPCConnError = rpcerrors.HumanError(err, apiEndpoints, Tea.ConfigFile("api.yaml"))
|
||||||
|
if isRPCConnError {
|
||||||
|
// API节点是否正在启动
|
||||||
|
var sock = gosock.NewTmpSock("edge-api")
|
||||||
|
reply, err := sock.SendTimeout(&gosock.Command{
|
||||||
|
Code: "starting",
|
||||||
|
Params: nil,
|
||||||
|
}, 1*time.Second)
|
||||||
|
if err == nil && reply != nil {
|
||||||
|
var params = maps.NewMap(reply.Params)
|
||||||
|
if params.GetBool("isStarting") {
|
||||||
|
apiNodeIsStarting = true
|
||||||
|
|
||||||
|
var progressMap = params.GetMap("progress")
|
||||||
|
apiNodeProgress = progressMap.GetString("description")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 本地的一些错误提示
|
||||||
|
if isRPCConnError {
|
||||||
|
host, _, hostErr := net.SplitHostPort(action.Object().Request.Host)
|
||||||
|
if hostErr == nil {
|
||||||
|
for _, endpoint := range apiEndpoints {
|
||||||
|
if strings.HasPrefix(endpoint, "http://"+host) || strings.HasPrefix(endpoint, "https://"+host) || strings.HasPrefix(endpoint, host) {
|
||||||
|
isLocalAPI = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isLocalAPI {
|
||||||
|
// 读取本地API节点的issues
|
||||||
|
issuesData, issuesErr := os.ReadFile(Tea.Root + "/edge-api/logs/issues.log")
|
||||||
|
if issuesErr == nil {
|
||||||
|
var issueMaps = []maps.Map{}
|
||||||
|
issuesErr = json.Unmarshal(issuesData, &issueMaps)
|
||||||
|
if issuesErr == nil && len(issueMaps) > 0 {
|
||||||
|
var issueMap = issueMaps[0]
|
||||||
|
issuesHTML = "本地API节点启动错误:" + issueMap.GetString("message") + ",处理建议:" + issueMap.GetString("suggestion")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,6 +39,17 @@ func (this *CreateBatchAction) RunGet(params struct {
|
|||||||
}
|
}
|
||||||
this.Data["leftMenuItems"] = leftMenuItems
|
this.Data["leftMenuItems"] = leftMenuItems
|
||||||
|
|
||||||
|
// 限额
|
||||||
|
maxNodes, leftNodes, err := this.findNodesQuota()
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.Data["quota"] = maps.Map{
|
||||||
|
"maxNodes": maxNodes,
|
||||||
|
"leftNodes": leftNodes,
|
||||||
|
}
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package cluster
|
||||||
|
|
||||||
|
func (this *CreateBatchAction) findNodesQuota() (maxNodes int32, leftNodes int32, err error) {
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -30,6 +30,11 @@ func (this *CreateNodeAction) Init() {
|
|||||||
func (this *CreateNodeAction) RunGet(params struct {
|
func (this *CreateNodeAction) RunGet(params struct {
|
||||||
ClusterId int64
|
ClusterId int64
|
||||||
}) {
|
}) {
|
||||||
|
if params.ClusterId <= 0 {
|
||||||
|
this.RedirectURL("/clusters")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var leftMenuItems = []maps.Map{
|
var leftMenuItems = []maps.Map{
|
||||||
{
|
{
|
||||||
"name": "单个创建",
|
"name": "单个创建",
|
||||||
@@ -92,6 +97,17 @@ func (this *CreateNodeAction) RunGet(params struct {
|
|||||||
// 安装文件下载
|
// 安装文件下载
|
||||||
this.Data["installerFiles"] = clusterutils.ListInstallerFiles()
|
this.Data["installerFiles"] = clusterutils.ListInstallerFiles()
|
||||||
|
|
||||||
|
// 限额
|
||||||
|
maxNodes, leftNodes, err := this.findNodesQuota()
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.Data["quota"] = maps.Map{
|
||||||
|
"maxNodes": maxNodes,
|
||||||
|
"leftNodes": leftNodes,
|
||||||
|
}
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package cluster
|
||||||
|
|
||||||
|
func (this *CreateNodeAction) findNodesQuota() (maxNodes int32, leftNodes int32, err error) {
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ func init() {
|
|||||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNode)).
|
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNode)).
|
||||||
Helper(clusters.NewClusterHelper()).
|
Helper(clusters.NewClusterHelper()).
|
||||||
Data("teaMenu", "clusters").
|
Data("teaMenu", "clusters").
|
||||||
|
Data("teaSubMenu", "cluster").
|
||||||
Prefix("/clusters/cluster").
|
Prefix("/clusters/cluster").
|
||||||
Get("", new(IndexAction)).
|
Get("", new(IndexAction)).
|
||||||
Get("/nodes", new(NodesAction)).
|
Get("/nodes", new(NodesAction)).
|
||||||
|
|||||||
@@ -187,6 +187,8 @@ func (this *DetailAction) RunGet(params struct {
|
|||||||
"route": route.Name,
|
"route": route.Name,
|
||||||
"value": addr.Ip,
|
"value": addr.Ip,
|
||||||
"clusterName": cluster.Name,
|
"clusterName": cluster.Name,
|
||||||
|
"isBackup": dnsInfo.IsBackupForCluster || dnsInfo.IsBackupForGroup,
|
||||||
|
"isOffline": dnsInfo.IsOffline,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,25 +345,29 @@ func (this *DetailAction) RunGet(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.Data["node"] = maps.Map{
|
this.Data["node"] = maps.Map{
|
||||||
"id": node.Id,
|
"id": node.Id,
|
||||||
"name": node.Name,
|
"name": node.Name,
|
||||||
"ipAddresses": ipAddressMaps,
|
"ipAddresses": ipAddressMaps,
|
||||||
"cluster": clusterMap,
|
"cluster": clusterMap,
|
||||||
"secondaryClusters": secondaryClustersMaps,
|
"secondaryClusters": secondaryClustersMaps,
|
||||||
"login": loginMap,
|
"login": loginMap,
|
||||||
"installDir": node.InstallDir,
|
"installDir": node.InstallDir,
|
||||||
"isInstalled": node.IsInstalled,
|
"isInstalled": node.IsInstalled,
|
||||||
"uniqueId": node.UniqueId,
|
"uniqueId": node.UniqueId,
|
||||||
"secret": node.Secret,
|
"secret": node.Secret,
|
||||||
"maxCPU": node.MaxCPU,
|
"maxCPU": node.MaxCPU,
|
||||||
"isOn": node.IsOn,
|
"isOn": node.IsOn,
|
||||||
"records": recordMaps,
|
"records": recordMaps,
|
||||||
"routes": routeMaps,
|
"routes": routeMaps,
|
||||||
"level": node.Level,
|
"level": node.Level,
|
||||||
"levelInfo": nodeconfigs.FindNodeLevel(int(node.Level)),
|
"levelInfo": nodeconfigs.FindNodeLevel(int(node.Level)),
|
||||||
"lnAddrs": lnAddrs,
|
"lnAddrs": lnAddrs,
|
||||||
"enableIPLists": node.EnableIPLists,
|
"enableIPLists": node.EnableIPLists,
|
||||||
"apiNodeAddrs": apiNodeAddrStrings,
|
"apiNodeAddrs": apiNodeAddrStrings,
|
||||||
|
"offlineDay": node.OfflineDay,
|
||||||
|
"isOffline": len(node.OfflineDay) > 0 && node.OfflineDay < timeutil.Format("Ymd"),
|
||||||
|
"isBackupForCluster": node.IsBackupForCluster,
|
||||||
|
"isBackupForGroup": node.IsBackupForGroup,
|
||||||
|
|
||||||
"status": maps.Map{
|
"status": maps.Map{
|
||||||
"isActive": status.IsActive,
|
"isActive": status.IsActive,
|
||||||
|
|||||||
@@ -209,6 +209,8 @@ func (this *NodesAction) RunGet(params struct {
|
|||||||
"isInstalled": node.IsInstalled,
|
"isInstalled": node.IsInstalled,
|
||||||
"isOn": node.IsOn,
|
"isOn": node.IsOn,
|
||||||
"isUp": node.IsUp,
|
"isUp": node.IsUp,
|
||||||
|
"isBackup": node.IsBackupForCluster || node.IsBackupForGroup,
|
||||||
|
"offlineDay": node.OfflineDay,
|
||||||
"installStatus": maps.Map{
|
"installStatus": maps.Map{
|
||||||
"isRunning": node.InstallStatus.IsRunning,
|
"isRunning": node.InstallStatus.IsRunning,
|
||||||
"isFinished": node.InstallStatus.IsFinished,
|
"isFinished": node.InstallStatus.IsFinished,
|
||||||
@@ -225,7 +227,7 @@ func (this *NodesAction) RunGet(params struct {
|
|||||||
"memUsageText": fmt.Sprintf("%.2f%%", status.MemoryUsage*100),
|
"memUsageText": fmt.Sprintf("%.2f%%", status.MemoryUsage*100),
|
||||||
"trafficInBytes": status.TrafficInBytes,
|
"trafficInBytes": status.TrafficInBytes,
|
||||||
"trafficOutBytes": status.TrafficOutBytes,
|
"trafficOutBytes": status.TrafficOutBytes,
|
||||||
"load1m": numberutils.FormatFloat2(status.Load1m),
|
"load1m": numberutils.PadFloatZero(numberutils.FormatFloat2(status.Load1m), 2),
|
||||||
"countConnections": status.ConnectionCount,
|
"countConnections": status.ConnectionCount,
|
||||||
},
|
},
|
||||||
"cluster": maps.Map{
|
"cluster": maps.Map{
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ p { color: grey; }
|
|||||||
</body>
|
</body>
|
||||||
</html>`
|
</html>`
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Data["httpAllDomainMismatchActionContentHTML"] = httpAllDomainMismatchActionContentHTML
|
this.Data["httpAllDomainMismatchActionContentHTML"] = httpAllDomainMismatchActionContentHTML
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
@@ -77,8 +78,12 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
HttpAllAllowMismatchDomainsJSON []byte
|
HttpAllAllowMismatchDomainsJSON []byte
|
||||||
HttpAllAllowNodeIP bool
|
HttpAllAllowNodeIP bool
|
||||||
HttpAllDefaultDomain string
|
HttpAllDefaultDomain string
|
||||||
|
HttpAllNodeIPPageHTML string
|
||||||
|
HttpAllNodeIPShowPage bool
|
||||||
|
HttpAllForceLnRequest bool
|
||||||
|
|
||||||
HttpAllSupportsLowVersionHTTP bool
|
HttpAllSupportsLowVersionHTTP bool
|
||||||
|
HttpAllMatchCertFromAllServers bool
|
||||||
|
|
||||||
HttpAccessLogEnableRequestHeaders bool
|
HttpAccessLogEnableRequestHeaders bool
|
||||||
HttpAccessLogEnableResponseHeaders bool
|
HttpAccessLogEnableResponseHeaders bool
|
||||||
@@ -135,9 +140,13 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
config.HTTPAll.AllowMismatchDomains = allowMismatchDomains
|
config.HTTPAll.AllowMismatchDomains = allowMismatchDomains
|
||||||
config.HTTPAll.AllowNodeIP = params.HttpAllAllowNodeIP
|
config.HTTPAll.AllowNodeIP = params.HttpAllAllowNodeIP
|
||||||
config.HTTPAll.DefaultDomain = params.HttpAllDefaultDomain
|
config.HTTPAll.DefaultDomain = params.HttpAllDefaultDomain
|
||||||
|
config.HTTPAll.NodeIPShowPage = params.HttpAllNodeIPShowPage
|
||||||
|
config.HTTPAll.NodeIPPageHTML = params.HttpAllNodeIPPageHTML
|
||||||
|
|
||||||
// HTTP All
|
// HTTP All
|
||||||
config.HTTPAll.SupportsLowVersionHTTP = params.HttpAllSupportsLowVersionHTTP
|
config.HTTPAll.SupportsLowVersionHTTP = params.HttpAllSupportsLowVersionHTTP
|
||||||
|
config.HTTPAll.MatchCertFromAllServers = params.HttpAllMatchCertFromAllServers
|
||||||
|
config.HTTPAll.ForceLnRequest = params.HttpAllForceLnRequest
|
||||||
|
|
||||||
// 访问日志
|
// 访问日志
|
||||||
config.HTTPAccessLog.EnableRequestHeaders = params.HttpAccessLogEnableRequestHeaders
|
config.HTTPAccessLog.EnableRequestHeaders = params.HttpAccessLogEnableRequestHeaders
|
||||||
|
|||||||
@@ -15,7 +15,17 @@ func (this *RunPopupAction) Init() {
|
|||||||
this.Nav("", "", "")
|
this.Nav("", "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RunPopupAction) RunGet(params struct{}) {
|
func (this *RunPopupAction) RunGet(params struct {
|
||||||
|
ClusterId int64
|
||||||
|
}) {
|
||||||
|
// 检查是否已部署服务
|
||||||
|
countServersResp, err := this.RPC().ServerRPC().CountAllEnabledServersWithNodeClusterId(this.AdminContext(), &pb.CountAllEnabledServersWithNodeClusterIdRequest{NodeClusterId: params.ClusterId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.Data["hasServers"] = countServersResp.Count > 0
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ func init() {
|
|||||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNode)).
|
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNode)).
|
||||||
Helper(clusters.NewClusterHelper()).
|
Helper(clusters.NewClusterHelper()).
|
||||||
Prefix("/clusters/cluster/settings").
|
Prefix("/clusters/cluster/settings").
|
||||||
|
Data("teaSubMenu", "cluster").
|
||||||
GetPost("", new(IndexAction)).
|
GetPost("", new(IndexAction)).
|
||||||
|
|
||||||
// 健康检查
|
// 健康检查
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ func (this *ClusterHelper) BeforeAction(actionPtr actions.ActionWrapper) (goNext
|
|||||||
|
|
||||||
action.Data["teaMenu"] = "clusters"
|
action.Data["teaMenu"] = "clusters"
|
||||||
|
|
||||||
selectedTabbar := action.Data.GetString("mainTab")
|
var selectedTabbar = action.Data.GetString("mainTab")
|
||||||
clusterId := action.ParamInt64("clusterId")
|
var clusterId = action.ParamInt64("clusterId")
|
||||||
clusterIdString := strconv.FormatInt(clusterId, 10)
|
var clusterIdString = strconv.FormatInt(clusterId, 10)
|
||||||
action.Data["clusterId"] = clusterId
|
action.Data["clusterId"] = clusterId
|
||||||
|
|
||||||
if clusterId > 0 {
|
if clusterId > 0 {
|
||||||
@@ -57,14 +57,45 @@ func (this *ClusterHelper) BeforeAction(actionPtr actions.ActionWrapper) (goNext
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nodeId = action.ParamInt64("nodeId")
|
||||||
|
var isInCluster = nodeId <= 0
|
||||||
|
|
||||||
var tabbar = actionutils.NewTabbar()
|
var tabbar = actionutils.NewTabbar()
|
||||||
tabbar.Add("集群列表", "", "/clusters", "", false)
|
{
|
||||||
if teaconst.IsPlus {
|
var url = "/clusters"
|
||||||
tabbar.Add("集群看板", "", "/clusters/cluster/boards?clusterId="+clusterIdString, "chart line area", selectedTabbar == "board")
|
if !isInCluster {
|
||||||
|
url = "/clusters/cluster/nodes?clusterId=" + clusterIdString
|
||||||
|
}
|
||||||
|
tabbar.Add("", "", url, "arrow left", false)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var url = "/clusters/cluster?clusterId=" + clusterIdString
|
||||||
|
if !isInCluster {
|
||||||
|
url = "/clusters/cluster/nodes?clusterId=" + clusterIdString
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = tabbar.Add(cluster.Name, "", url, "angle right", true)
|
||||||
|
item.IsTitle = true
|
||||||
|
}
|
||||||
|
if teaconst.IsPlus {
|
||||||
|
{
|
||||||
|
var item = tabbar.Add("集群看板", "", "/clusters/cluster/boards?clusterId="+clusterIdString, "chart line area", selectedTabbar == "board")
|
||||||
|
item.IsDisabled = !isInCluster
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var item = tabbar.Add("节点列表", "", "/clusters/cluster/nodes?clusterId="+clusterIdString, "server", selectedTabbar == "node")
|
||||||
|
item.IsDisabled = !isInCluster
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var item = tabbar.Add("集群设置", "", "/clusters/cluster/settings?clusterId="+clusterIdString, "setting", selectedTabbar == "setting")
|
||||||
|
item.IsDisabled = !isInCluster
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var item = tabbar.Add("删除集群", "", "/clusters/cluster/delete?clusterId="+clusterIdString, "trash", selectedTabbar == "delete")
|
||||||
|
item.IsDisabled = !isInCluster
|
||||||
}
|
}
|
||||||
tabbar.Add("集群节点", "", "/clusters/cluster/nodes?clusterId="+clusterIdString, "server", selectedTabbar == "node")
|
|
||||||
tabbar.Add("集群设置", "", "/clusters/cluster/settings?clusterId="+clusterIdString, "setting", selectedTabbar == "setting")
|
|
||||||
tabbar.Add("删除集群", "", "/clusters/cluster/delete?clusterId="+clusterIdString, "trash", selectedTabbar == "delete")
|
|
||||||
actionutils.SetTabbar(action, tabbar)
|
actionutils.SetTabbar(action, tabbar)
|
||||||
|
|
||||||
// 左侧菜单
|
// 左侧菜单
|
||||||
@@ -97,14 +128,39 @@ func (this *ClusterHelper) createSettingMenu(cluster *pb.NodeCluster, info *pb.F
|
|||||||
"isActive": selectedItem == "basic",
|
"isActive": selectedItem == "basic",
|
||||||
"isOn": true,
|
"isOn": true,
|
||||||
})
|
})
|
||||||
|
|
||||||
items = append(items, maps.Map{
|
items = append(items, maps.Map{
|
||||||
"name": "缓存设置",
|
"name": "DNS设置",
|
||||||
|
"url": "/clusters/cluster/settings/dns?clusterId=" + clusterId,
|
||||||
|
"isActive": selectedItem == "dns",
|
||||||
|
"isOn": cluster.DnsDomainId > 0 || len(cluster.DnsName) > 0,
|
||||||
|
})
|
||||||
|
items = append(items, maps.Map{
|
||||||
|
"name": "健康检查",
|
||||||
|
"url": "/clusters/cluster/settings/health?clusterId=" + clusterId,
|
||||||
|
"isActive": selectedItem == "health",
|
||||||
|
"isOn": info != nil && info.HealthCheckIsOn,
|
||||||
|
})
|
||||||
|
|
||||||
|
items = append(items, maps.Map{
|
||||||
|
"name": "-",
|
||||||
|
})
|
||||||
|
|
||||||
|
items = append(items, maps.Map{
|
||||||
|
"name": "网站设置",
|
||||||
|
"url": "/clusters/cluster/settings/global-server-config?clusterId=" + clusterId,
|
||||||
|
"isActive": selectedItem == "globalServerConfig",
|
||||||
|
"isOn": true,
|
||||||
|
})
|
||||||
|
|
||||||
|
items = append(items, maps.Map{
|
||||||
|
"name": "缓存策略",
|
||||||
"url": "/clusters/cluster/settings/cache?clusterId=" + clusterId,
|
"url": "/clusters/cluster/settings/cache?clusterId=" + clusterId,
|
||||||
"isActive": selectedItem == "cache",
|
"isActive": selectedItem == "cache",
|
||||||
"isOn": cluster.HttpCachePolicyId > 0,
|
"isOn": cluster.HttpCachePolicyId > 0,
|
||||||
})
|
})
|
||||||
items = append(items, maps.Map{
|
items = append(items, maps.Map{
|
||||||
"name": "WAF设置",
|
"name": "WAF策略",
|
||||||
"url": "/clusters/cluster/settings/waf?clusterId=" + clusterId,
|
"url": "/clusters/cluster/settings/waf?clusterId=" + clusterId,
|
||||||
"isActive": selectedItem == "waf",
|
"isActive": selectedItem == "waf",
|
||||||
"isOn": cluster.HttpFirewallPolicyId > 0,
|
"isOn": cluster.HttpFirewallPolicyId > 0,
|
||||||
@@ -132,20 +188,6 @@ func (this *ClusterHelper) createSettingMenu(cluster *pb.NodeCluster, info *pb.F
|
|||||||
"isActive": false,
|
"isActive": false,
|
||||||
})
|
})
|
||||||
|
|
||||||
items = append(items, maps.Map{
|
|
||||||
"name": "DNS设置",
|
|
||||||
"url": "/clusters/cluster/settings/dns?clusterId=" + clusterId,
|
|
||||||
"isActive": selectedItem == "dns",
|
|
||||||
"isOn": cluster.DnsDomainId > 0 || len(cluster.DnsName) > 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
items = append(items, maps.Map{
|
|
||||||
"name": "健康检查",
|
|
||||||
"url": "/clusters/cluster/settings/health?clusterId=" + clusterId,
|
|
||||||
"isActive": selectedItem == "health",
|
|
||||||
"isOn": info != nil && info.HealthCheckIsOn,
|
|
||||||
})
|
|
||||||
|
|
||||||
items = append(items, maps.Map{
|
items = append(items, maps.Map{
|
||||||
"name": "DDoS防护",
|
"name": "DDoS防护",
|
||||||
"url": "/clusters/cluster/settings/ddos-protection?clusterId=" + clusterId,
|
"url": "/clusters/cluster/settings/ddos-protection?clusterId=" + clusterId,
|
||||||
@@ -153,13 +195,6 @@ func (this *ClusterHelper) createSettingMenu(cluster *pb.NodeCluster, info *pb.F
|
|||||||
"isOn": info != nil && info.HasDDoSProtection,
|
"isOn": info != nil && info.HasDDoSProtection,
|
||||||
})
|
})
|
||||||
|
|
||||||
items = append(items, maps.Map{
|
|
||||||
"name": "服务设置",
|
|
||||||
"url": "/clusters/cluster/settings/global-server-config?clusterId=" + clusterId,
|
|
||||||
"isActive": selectedItem == "globalServerConfig",
|
|
||||||
"isOn": true,
|
|
||||||
})
|
|
||||||
|
|
||||||
items = append(items, maps.Map{
|
items = append(items, maps.Map{
|
||||||
"name": "-",
|
"name": "-",
|
||||||
})
|
})
|
||||||
|
|||||||
52
internal/web/actions/default/clusters/createNode.go
Normal file
52
internal/web/actions/default/clusters/createNode.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package clusters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateNodeAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreateNodeAction) Init() {
|
||||||
|
this.Nav("", "cluster", "createNode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreateNodeAction) RunGet(params struct{}) {
|
||||||
|
// 集群总数
|
||||||
|
totalClustersResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.Data["totalNodeClusters"] = totalClustersResp.Count
|
||||||
|
|
||||||
|
// 节点总数
|
||||||
|
totalNodesResp, err := this.RPC().NodeRPC().CountAllEnabledNodes(this.AdminContext(), &pb.CountAllEnabledNodesRequest{})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.Data["totalNodes"] = totalNodesResp.Count
|
||||||
|
|
||||||
|
// 如果只有一个默认集群,那么直接跳转到集群
|
||||||
|
clustersResp, err := this.RPC().NodeClusterRPC().ListEnabledNodeClusters(this.AdminContext(), &pb.ListEnabledNodeClustersRequest{
|
||||||
|
Offset: 0,
|
||||||
|
Size: 2,
|
||||||
|
Keyword: "",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(clustersResp.NodeClusters) == 1 {
|
||||||
|
this.RedirectURL("/clusters/cluster/createNode?clusterId=" + types.String(clustersResp.NodeClusters[0].Id))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
@@ -13,9 +13,11 @@ func init() {
|
|||||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNode)).
|
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNode)).
|
||||||
Helper(clusterutils.NewClustersHelper()).
|
Helper(clusterutils.NewClustersHelper()).
|
||||||
Data("teaMenu", "clusters").
|
Data("teaMenu", "clusters").
|
||||||
|
Data("teaSubMenu", "cluster").
|
||||||
Prefix("/clusters").
|
Prefix("/clusters").
|
||||||
Get("", new(IndexAction)).
|
Get("", new(IndexAction)).
|
||||||
GetPost("/create", new(CreateAction)).
|
GetPost("/create", new(CreateAction)).
|
||||||
|
GetPost("/createNode", new(CreateNodeAction)).
|
||||||
Post("/pin", new(PinAction)).
|
Post("/pin", new(PinAction)).
|
||||||
Get("/nodes", new(NodesAction)).
|
Get("/nodes", new(NodesAction)).
|
||||||
|
|
||||||
|
|||||||
@@ -211,6 +211,8 @@ func (this *NodesAction) RunGet(params struct {
|
|||||||
"isInstalled": node.IsInstalled,
|
"isInstalled": node.IsInstalled,
|
||||||
"isOn": node.IsOn,
|
"isOn": node.IsOn,
|
||||||
"isUp": node.IsUp,
|
"isUp": node.IsUp,
|
||||||
|
"isBackup": node.IsBackupForCluster || node.IsBackupForGroup,
|
||||||
|
"offlineDay": node.OfflineDay,
|
||||||
"installStatus": maps.Map{
|
"installStatus": maps.Map{
|
||||||
"isRunning": node.InstallStatus.IsRunning,
|
"isRunning": node.InstallStatus.IsRunning,
|
||||||
"isFinished": node.InstallStatus.IsFinished,
|
"isFinished": node.InstallStatus.IsFinished,
|
||||||
@@ -222,12 +224,12 @@ func (this *NodesAction) RunGet(params struct {
|
|||||||
"updatedAt": status.UpdatedAt,
|
"updatedAt": status.UpdatedAt,
|
||||||
"hostname": status.Hostname,
|
"hostname": status.Hostname,
|
||||||
"cpuUsage": status.CPUUsage,
|
"cpuUsage": status.CPUUsage,
|
||||||
"cpuUsageText": numberutils.FormatFloat2(status.CPUUsage * 100),
|
"cpuUsageText": numberutils.FormatFloat2(status.CPUUsage*100) + "%",
|
||||||
"memUsage": status.MemoryUsage,
|
"memUsage": status.MemoryUsage,
|
||||||
"memUsageText": numberutils.FormatFloat2(status.MemoryUsage * 100),
|
"memUsageText": numberutils.FormatFloat2(status.MemoryUsage*100) + "%",
|
||||||
"trafficInBytes": status.TrafficInBytes,
|
"trafficInBytes": status.TrafficInBytes,
|
||||||
"trafficOutBytes": status.TrafficOutBytes,
|
"trafficOutBytes": status.TrafficOutBytes,
|
||||||
"load1m": numberutils.FormatFloat2(status.Load1m),
|
"load1m": numberutils.PadFloatZero(numberutils.FormatFloat2(status.Load1m), 2),
|
||||||
"countConnections": status.ConnectionCount,
|
"countConnections": status.ConnectionCount,
|
||||||
},
|
},
|
||||||
"cluster": maps.Map{
|
"cluster": maps.Map{
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ func (this *CheckAction) RunPost(params struct {
|
|||||||
HasError bool
|
HasError bool
|
||||||
IsUpdated bool
|
IsUpdated bool
|
||||||
}) {
|
}) {
|
||||||
|
var isStream = this.Request.ProtoMajor >= 2
|
||||||
|
this.Data["isStream"] = isStream
|
||||||
|
|
||||||
var maxTries = 10
|
var maxTries = 10
|
||||||
for i := 0; i < maxTries; i++ {
|
for i := 0; i < maxTries; i++ {
|
||||||
resp, err := this.RPC().NodeTaskRPC().ExistsNodeTasks(this.AdminContext(), &pb.ExistsNodeTasksRequest{
|
resp, err := this.RPC().NodeTaskRPC().ExistsNodeTasks(this.AdminContext(), &pb.ExistsNodeTasksRequest{
|
||||||
@@ -26,7 +29,7 @@ func (this *CheckAction) RunPost(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 如果没有数据变化,继续查询
|
// 如果没有数据变化,继续查询
|
||||||
if i < maxTries-1 && params.IsUpdated && resp.ExistTasks == params.IsDoing && resp.ExistError == params.HasError {
|
if i < maxTries-1 && params.IsUpdated && resp.ExistTasks == params.IsDoing && resp.ExistError == params.HasError && isStream {
|
||||||
time.Sleep(3 * time.Second)
|
time.Sleep(3 * time.Second)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,6 +136,8 @@ func (this *ClusterAction) RunGet(params struct {
|
|||||||
"clusterId": node.NodeClusterId,
|
"clusterId": node.NodeClusterId,
|
||||||
"isResolved": isResolved,
|
"isResolved": isResolved,
|
||||||
"isInstalled": isInstalled,
|
"isInstalled": isInstalled,
|
||||||
|
"isBackup": node.IsBackupForCluster || node.IsBackupForGroup,
|
||||||
|
"isOffline": node.IsOffline,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -171,6 +173,8 @@ func (this *ClusterAction) RunGet(params struct {
|
|||||||
"clusterId": node.NodeClusterId,
|
"clusterId": node.NodeClusterId,
|
||||||
"isResolved": isResolved,
|
"isResolved": isResolved,
|
||||||
"isInstalled": isInstalled,
|
"isInstalled": isInstalled,
|
||||||
|
"isBackup": node.IsBackupForCluster || node.IsBackupForGroup,
|
||||||
|
"isOffline": node.IsOffline,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DomainOptionsAction 域名列表选项
|
// DomainOptionsAction 域名列表选项
|
||||||
@@ -21,10 +22,18 @@ func (this *DomainOptionsAction) RunPost(params struct {
|
|||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
domainMaps := []maps.Map{}
|
|
||||||
|
// 排序
|
||||||
|
if len(domainsResp.DnsDomains) > 0 {
|
||||||
|
sort.Slice(domainsResp.DnsDomains, func(i, j int) bool {
|
||||||
|
return domainsResp.DnsDomains[i].Name < domainsResp.DnsDomains[j].Name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var domainMaps = []maps.Map{}
|
||||||
for _, domain := range domainsResp.DnsDomains {
|
for _, domain := range domainsResp.DnsDomains {
|
||||||
// 未开启或者已删除的先跳过
|
// 未开启或者已删除的先跳过
|
||||||
if !domain.IsOn || domain.IsDeleted {
|
if !domain.IsOn || domain.IsDeleted || !domain.IsUp {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ func init() {
|
|||||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeDNS)).
|
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeDNS)).
|
||||||
Helper(new(Helper)).
|
Helper(new(Helper)).
|
||||||
Prefix("/dns").
|
Prefix("/dns").
|
||||||
|
Data("teaSubMenu", "cluster").
|
||||||
Get("", new(IndexAction)).
|
Get("", new(IndexAction)).
|
||||||
GetPost("/updateClusterPopup", new(UpdateClusterPopupAction)).
|
GetPost("/updateClusterPopup", new(UpdateClusterPopupAction)).
|
||||||
Post("/providerOptions", new(ProviderOptionsAction)).
|
Post("/providerOptions", new(ProviderOptionsAction)).
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ func (this *CheckAction) RunPost(params struct {
|
|||||||
HasError bool
|
HasError bool
|
||||||
IsUpdated bool
|
IsUpdated bool
|
||||||
}) {
|
}) {
|
||||||
|
var isStream = this.Request.ProtoMajor >= 2
|
||||||
|
this.Data["isStream"] = isStream
|
||||||
|
|
||||||
var maxTries = 10
|
var maxTries = 10
|
||||||
for i := 0; i < maxTries; i++ {
|
for i := 0; i < maxTries; i++ {
|
||||||
resp, err := this.RPC().DNSTaskRPC().ExistsDNSTasks(this.AdminContext(), &pb.ExistsDNSTasksRequest{})
|
resp, err := this.RPC().DNSTaskRPC().ExistsDNSTasks(this.AdminContext(), &pb.ExistsDNSTasksRequest{})
|
||||||
@@ -24,7 +27,7 @@ func (this *CheckAction) RunPost(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 如果没有数据变化,继续查询
|
// 如果没有数据变化,继续查询
|
||||||
if i < maxTries-1 && params.IsUpdated && resp.ExistTasks == params.IsDoing && resp.ExistError == params.HasError {
|
if i < maxTries-1 && params.IsUpdated && resp.ExistTasks == params.IsDoing && resp.ExistError == params.HasError && isStream {
|
||||||
time.Sleep(3 * time.Second)
|
time.Sleep(3 * time.Second)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,15 +13,19 @@ import (
|
|||||||
adminserverutils "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/server/admin-server-utils"
|
adminserverutils "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/server/admin-server-utils"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
|
||||||
"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/lists"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const regionDenyMessage = "当前软件系统暂时不为你所在的区域提供服务。"
|
||||||
|
|
||||||
type IndexAction struct {
|
type IndexAction struct {
|
||||||
actionutils.ParentAction
|
actionutils.ParentAction
|
||||||
}
|
}
|
||||||
@@ -36,6 +40,11 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
|
|
||||||
Auth *helpers.UserShouldAuth
|
Auth *helpers.UserShouldAuth
|
||||||
}) {
|
}) {
|
||||||
|
if !this.checkRegion() {
|
||||||
|
this.WriteString(regionDenyMessage)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 是否自动从HTTP跳转到HTTPS
|
// 是否自动从HTTP跳转到HTTPS
|
||||||
if this.Request.TLS == nil {
|
if this.Request.TLS == nil {
|
||||||
httpsPort, _ := adminserverutils.ReadServerHTTPS()
|
httpsPort, _ := adminserverutils.ReadServerHTTPS()
|
||||||
@@ -50,8 +59,11 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
newHost += ":" + types.String(httpsPort)
|
newHost += ":" + types.String(httpsPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.RedirectURL("https://" + newHost + this.Request.RequestURI)
|
// 如果没有前端反向代理,则跳转
|
||||||
return
|
if len(this.Request.Header.Get("X-Forwarded-For")) == 0 && len(this.Request.Header.Get("X-Real-Ip")) == 0 {
|
||||||
|
this.RedirectURL("https://" + newHost + this.Request.RequestURI)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,6 +134,11 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
Auth *helpers.UserShouldAuth
|
Auth *helpers.UserShouldAuth
|
||||||
CSRF *actionutils.CSRF
|
CSRF *actionutils.CSRF
|
||||||
}) {
|
}) {
|
||||||
|
if !this.checkRegion() {
|
||||||
|
this.Fail(regionDenyMessage)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
params.Must.
|
params.Must.
|
||||||
Field("username", params.Username).
|
Field("username", params.Username).
|
||||||
Require("请输入用户名").
|
Require("请输入用户名").
|
||||||
@@ -213,3 +230,13 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
|
|
||||||
this.Success()
|
this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查登录区域
|
||||||
|
func (this *IndexAction) checkRegion() bool {
|
||||||
|
var ip = this.RequestRemoteIP()
|
||||||
|
var result = iplibrary.LookupIP(ip)
|
||||||
|
if result != nil && result.IsOk() && result.CountryId() > 0 && lists.ContainsInt64([]int64{9, 10}, result.CountryId()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,16 +4,41 @@ package loginutils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||||
"github.com/iwind/TeaGo/actions"
|
"github.com/iwind/TeaGo/actions"
|
||||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CalculateClientFingerprint 计算客户端指纹
|
// CalculateClientFingerprint 计算客户端指纹
|
||||||
func CalculateClientFingerprint(action *actions.ActionObject) string {
|
func CalculateClientFingerprint(action *actions.ActionObject) string {
|
||||||
return stringutil.Md5(action.RequestRemoteIP() + "@" + action.Request.UserAgent())
|
return stringutil.Md5(RemoteIP(action) + "@" + action.Request.UserAgent())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoteIP 获取客户端IP
|
||||||
|
// TODO 将来增加是否使用代理设置(即从X-Real-IP中获取IP)
|
||||||
|
func RemoteIP(action *actions.ActionObject) string {
|
||||||
|
ip, _, _ := net.SplitHostPort(action.Request.RemoteAddr)
|
||||||
|
return ip
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupIPRegion 查找登录区域
|
||||||
|
func LookupIPRegion(ip string) string {
|
||||||
|
if len(ip) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = iplibrary.LookupIP(ip)
|
||||||
|
if result != nil && result.IsOk() {
|
||||||
|
// 这里不需要网络运营商信息
|
||||||
|
return result.CountryName() + "@" + result.ProvinceName() + "@" + result.CityName() + "@" + result.TownName()
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCookie 设置Cookie
|
||||||
func SetCookie(action *actions.ActionObject, remember bool) {
|
func SetCookie(action *actions.ActionObject, remember bool) {
|
||||||
if remember {
|
if remember {
|
||||||
var cookie = &http.Cookie{
|
var cookie = &http.Cookie{
|
||||||
@@ -44,6 +69,7 @@ func SetCookie(action *actions.ActionObject, remember bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnsetCookie 重置Cookie
|
||||||
func UnsetCookie(action *actions.ActionObject) {
|
func UnsetCookie(action *actions.ActionObject) {
|
||||||
cookie := &http.Cookie{
|
cookie := &http.Cookie{
|
||||||
Name: teaconst.CookieSID,
|
Name: teaconst.CookieSID,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/iwind/TeaGo/actions"
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -27,6 +28,8 @@ func (this *AddOriginPopupAction) RunGet(params struct {
|
|||||||
}) {
|
}) {
|
||||||
this.Data["serverType"] = params.ServerType
|
this.Data["serverType"] = params.ServerType
|
||||||
|
|
||||||
|
this.getOSSHook()
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,50 +43,93 @@ func (this *AddOriginPopupAction) RunPost(params struct {
|
|||||||
|
|
||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
}) {
|
}) {
|
||||||
params.Must.
|
ossConfig, goNext, err := this.postOSSHook(params.Protocol)
|
||||||
Field("addr", params.Addr).
|
if err != nil {
|
||||||
Require("请输入源站地址")
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
var addr = params.Addr
|
}
|
||||||
|
if !goNext {
|
||||||
// 是否是完整的地址
|
return
|
||||||
if (params.Protocol == "http" || params.Protocol == "https") && regexp.MustCompile(`^(http|https)://`).MatchString(addr) {
|
|
||||||
u, err := url.Parse(addr)
|
|
||||||
if err == nil {
|
|
||||||
addr = u.Host
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = regexp.MustCompile(`\s+`).ReplaceAllString(addr, "")
|
// 初始化
|
||||||
var portIndex = strings.LastIndex(addr, ":")
|
var pbAddr = &pb.NetworkAddress{
|
||||||
if portIndex < 0 {
|
Protocol: params.Protocol,
|
||||||
if params.Protocol == "http" {
|
|
||||||
addr += ":80"
|
|
||||||
} else if params.Protocol == "https" {
|
|
||||||
addr += ":443"
|
|
||||||
} else {
|
|
||||||
this.Fail("地址中需要带有端口")
|
|
||||||
}
|
|
||||||
portIndex = strings.LastIndex(addr, ":")
|
|
||||||
}
|
}
|
||||||
var host = addr[:portIndex]
|
var addrConfig = &serverconfigs.NetworkAddressConfig{
|
||||||
var port = addr[portIndex+1:]
|
Protocol: serverconfigs.Protocol(params.Protocol),
|
||||||
|
}
|
||||||
|
var ossJSON []byte
|
||||||
|
|
||||||
// 检查端口号
|
if ossConfig != nil { // OSS
|
||||||
if port == "0" {
|
ossJSON, err = json.Marshal(ossConfig)
|
||||||
this.Fail("端口号不能为0")
|
if err != nil {
|
||||||
}
|
this.ErrorPage(err)
|
||||||
if !configutils.HasVariables(port) {
|
return
|
||||||
// 必须是整数
|
|
||||||
if !regexp.MustCompile(`^\d+$`).MatchString(port) {
|
|
||||||
this.Fail("端口号只能为整数")
|
|
||||||
}
|
}
|
||||||
var portInt = types.Int(port)
|
err = ossConfig.Init()
|
||||||
if portInt == 0 {
|
if err != nil {
|
||||||
|
this.Fail("校验OSS配置时出错:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else { // 普通源站
|
||||||
|
params.Must.
|
||||||
|
Field("addr", params.Addr).
|
||||||
|
Require("请输入源站地址")
|
||||||
|
|
||||||
|
var addr = params.Addr
|
||||||
|
|
||||||
|
// 是否是完整的地址
|
||||||
|
if (params.Protocol == "http" || params.Protocol == "https") && regexp.MustCompile(`^(http|https)://`).MatchString(addr) {
|
||||||
|
u, err := url.Parse(addr)
|
||||||
|
if err == nil {
|
||||||
|
addr = u.Host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = regexp.MustCompile(`\s+`).ReplaceAllString(addr, "")
|
||||||
|
var portIndex = strings.LastIndex(addr, ":")
|
||||||
|
if portIndex < 0 {
|
||||||
|
if params.Protocol == "http" {
|
||||||
|
addr += ":80"
|
||||||
|
} else if params.Protocol == "https" {
|
||||||
|
addr += ":443"
|
||||||
|
} else {
|
||||||
|
this.Fail("地址中需要带有端口")
|
||||||
|
}
|
||||||
|
portIndex = strings.LastIndex(addr, ":")
|
||||||
|
}
|
||||||
|
var host = addr[:portIndex]
|
||||||
|
var port = addr[portIndex+1:]
|
||||||
|
|
||||||
|
// 检查端口号
|
||||||
|
if port == "0" {
|
||||||
this.Fail("端口号不能为0")
|
this.Fail("端口号不能为0")
|
||||||
}
|
}
|
||||||
if portInt > 65535 {
|
if !configutils.HasVariables(port) {
|
||||||
this.Fail("端口号不能大于65535")
|
// 必须是整数
|
||||||
|
if !regexp.MustCompile(`^\d+$`).MatchString(port) {
|
||||||
|
this.Fail("端口号只能为整数")
|
||||||
|
}
|
||||||
|
var portInt = types.Int(port)
|
||||||
|
if portInt == 0 {
|
||||||
|
this.Fail("端口号不能为0")
|
||||||
|
}
|
||||||
|
if portInt > 65535 {
|
||||||
|
this.Fail("端口号不能大于65535")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pbAddr = &pb.NetworkAddress{
|
||||||
|
Protocol: params.Protocol,
|
||||||
|
Host: host,
|
||||||
|
PortRange: port,
|
||||||
|
}
|
||||||
|
|
||||||
|
addrConfig = &serverconfigs.NetworkAddressConfig{
|
||||||
|
Protocol: serverconfigs.Protocol(params.Protocol),
|
||||||
|
Host: host,
|
||||||
|
PortRange: port,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,12 +149,9 @@ func (this *AddOriginPopupAction) RunPost(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp, err := this.RPC().OriginRPC().CreateOrigin(this.AdminContext(), &pb.CreateOriginRequest{
|
resp, err := this.RPC().OriginRPC().CreateOrigin(this.AdminContext(), &pb.CreateOriginRequest{
|
||||||
Name: "",
|
Name: "",
|
||||||
Addr: &pb.NetworkAddress{
|
Addr: pbAddr,
|
||||||
Protocol: params.Protocol,
|
OssJSON: ossJSON,
|
||||||
Host: host,
|
|
||||||
PortRange: port,
|
|
||||||
},
|
|
||||||
Description: "",
|
Description: "",
|
||||||
Weight: 10,
|
Weight: 10,
|
||||||
IsOn: true,
|
IsOn: true,
|
||||||
@@ -124,14 +167,16 @@ func (this *AddOriginPopupAction) RunPost(params struct {
|
|||||||
var origin = &serverconfigs.OriginConfig{
|
var origin = &serverconfigs.OriginConfig{
|
||||||
Id: resp.OriginId,
|
Id: resp.OriginId,
|
||||||
IsOn: true,
|
IsOn: true,
|
||||||
Addr: &serverconfigs.NetworkAddressConfig{
|
Addr: addrConfig,
|
||||||
Protocol: serverconfigs.Protocol(params.Protocol),
|
OSS: ossConfig,
|
||||||
Host: host,
|
|
||||||
PortRange: port,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Data["origin"] = origin
|
this.Data["origin"] = maps.Map{
|
||||||
|
"id": resp.OriginId,
|
||||||
|
"isOn": true,
|
||||||
|
"addr": addrConfig,
|
||||||
|
"addrSummary": origin.AddrSummary(),
|
||||||
|
}
|
||||||
|
|
||||||
// 创建日志
|
// 创建日志
|
||||||
defer this.CreateLog(oplogs.LevelInfo, "创建源站 %d", resp.OriginId)
|
defer this.CreateLog(oplogs.LevelInfo, "创建源站 %d", resp.OriginId)
|
||||||
|
|||||||
20
internal/web/actions/default/servers/addOriginPopup_ext.go
Normal file
20
internal/web/actions/default/servers/addOriginPopup_ext.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package servers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ossconfigs"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this *AddOriginPopupAction) getOSSHook() {
|
||||||
|
this.Data["ossTypes"] = []maps.Map{}
|
||||||
|
this.Data["ossBucketParams"] = []maps.Map{}
|
||||||
|
this.Data["ossForm"] = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *AddOriginPopupAction) postOSSHook(protocol string) (config *ossconfigs.OSSConfig, goNext bool, err error) {
|
||||||
|
goNext = true
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -18,31 +18,6 @@ func (this *CreateAction) Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *CreateAction) RunGet(params struct{}) {
|
func (this *CreateAction) RunGet(params struct{}) {
|
||||||
// 获取所有可用的用户
|
|
||||||
usersResp, err := this.RPC().ACMEUserRPC().FindAllACMEUsers(this.AdminContext(), &pb.FindAllACMEUsersRequest{
|
|
||||||
AdminId: this.AdminId(),
|
|
||||||
UserId: 0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
this.ErrorPage(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
userMaps := []maps.Map{}
|
|
||||||
for _, user := range usersResp.AcmeUsers {
|
|
||||||
description := user.Description
|
|
||||||
if len(description) > 0 {
|
|
||||||
description = "(" + description + ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
userMaps = append(userMaps, maps.Map{
|
|
||||||
"id": user.Id,
|
|
||||||
"description": description,
|
|
||||||
"email": user.Email,
|
|
||||||
"providerCode": user.AcmeProviderCode,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.Data["users"] = userMaps
|
|
||||||
|
|
||||||
// 证书服务商
|
// 证书服务商
|
||||||
providersResp, err := this.RPC().ACMEProviderRPC().FindAllACMEProviders(this.AdminContext(), &pb.FindAllACMEProvidersRequest{})
|
providersResp, err := this.RPC().ACMEProviderRPC().FindAllACMEProviders(this.AdminContext(), &pb.FindAllACMEProvidersRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -81,14 +56,15 @@ func (this *CreateAction) RunGet(params struct{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *CreateAction) RunPost(params struct {
|
func (this *CreateAction) RunPost(params struct {
|
||||||
TaskId int64
|
PlatformUserId int64
|
||||||
AuthType string
|
TaskId int64
|
||||||
AcmeUserId int64
|
AuthType string
|
||||||
DnsProviderId int64
|
AcmeUserId int64
|
||||||
DnsDomain string
|
DnsProviderId int64
|
||||||
Domains []string
|
DnsDomain string
|
||||||
AutoRenew bool
|
Domains []string
|
||||||
AuthURL string
|
AutoRenew bool
|
||||||
|
AuthURL string
|
||||||
|
|
||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
}) {
|
}) {
|
||||||
@@ -117,7 +93,7 @@ func (this *CreateAction) RunPost(params struct {
|
|||||||
if len(params.Domains) == 0 {
|
if len(params.Domains) == 0 {
|
||||||
this.Fail("请输入证书域名列表")
|
this.Fail("请输入证书域名列表")
|
||||||
}
|
}
|
||||||
realDomains := []string{}
|
var realDomains = []string{}
|
||||||
for _, domain := range params.Domains {
|
for _, domain := range params.Domains {
|
||||||
domain = strings.ToLower(domain)
|
domain = strings.ToLower(domain)
|
||||||
if params.AuthType == "dns" { // DNS认证
|
if params.AuthType == "dns" { // DNS认证
|
||||||
@@ -134,6 +110,7 @@ func (this *CreateAction) RunPost(params struct {
|
|||||||
|
|
||||||
if params.TaskId == 0 {
|
if params.TaskId == 0 {
|
||||||
createResp, err := this.RPC().ACMETaskRPC().CreateACMETask(this.AdminContext(), &pb.CreateACMETaskRequest{
|
createResp, err := this.RPC().ACMETaskRPC().CreateACMETask(this.AdminContext(), &pb.CreateACMETaskRequest{
|
||||||
|
UserId: params.PlatformUserId,
|
||||||
AuthType: params.AuthType,
|
AuthType: params.AuthType,
|
||||||
AcmeUserId: params.AcmeUserId,
|
AcmeUserId: params.AcmeUserId,
|
||||||
DnsProviderId: params.DnsProviderId,
|
DnsProviderId: params.DnsProviderId,
|
||||||
|
|||||||
@@ -17,22 +17,48 @@ func (this *IndexAction) Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *IndexAction) RunGet(params struct {
|
func (this *IndexAction) RunGet(params struct {
|
||||||
|
UserId int64
|
||||||
Type string
|
Type string
|
||||||
Keyword string
|
Keyword string
|
||||||
}) {
|
}) {
|
||||||
this.Data["type"] = params.Type
|
this.Data["type"] = params.Type
|
||||||
this.Data["keyword"] = params.Keyword
|
this.Data["keyword"] = params.Keyword
|
||||||
|
|
||||||
countAll := int64(0)
|
// 当前用户
|
||||||
countAvailable := int64(0)
|
this.Data["searchingUserId"] = params.UserId
|
||||||
countExpired := int64(0)
|
var userMap = maps.Map{
|
||||||
count7Days := int64(0)
|
"id": 0,
|
||||||
count30Days := int64(0)
|
"username": "",
|
||||||
|
"fullname": "",
|
||||||
|
}
|
||||||
|
if params.UserId > 0 {
|
||||||
|
userResp, err := this.RPC().UserRPC().FindEnabledUser(this.AdminContext(), &pb.FindEnabledUserRequest{UserId: params.UserId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var user = userResp.User
|
||||||
|
if user != nil {
|
||||||
|
userMap = maps.Map{
|
||||||
|
"id": user.Id,
|
||||||
|
"username": user.Username,
|
||||||
|
"fullname": user.Fullname,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Data["user"] = userMap
|
||||||
|
|
||||||
|
var countAll int64
|
||||||
|
var countAvailable int64
|
||||||
|
var countExpired int64
|
||||||
|
var count7Days int64
|
||||||
|
var count30Days int64
|
||||||
|
|
||||||
// 计算数量
|
// 计算数量
|
||||||
{
|
{
|
||||||
// all
|
// all
|
||||||
resp, err := this.RPC().ACMETaskRPC().CountAllEnabledACMETasks(this.AdminContext(), &pb.CountAllEnabledACMETasksRequest{
|
resp, err := this.RPC().ACMETaskRPC().CountAllEnabledACMETasks(this.AdminContext(), &pb.CountAllEnabledACMETasksRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -43,6 +69,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
|
|
||||||
// available
|
// available
|
||||||
resp, err = this.RPC().ACMETaskRPC().CountAllEnabledACMETasks(this.AdminContext(), &pb.CountAllEnabledACMETasksRequest{
|
resp, err = this.RPC().ACMETaskRPC().CountAllEnabledACMETasks(this.AdminContext(), &pb.CountAllEnabledACMETasksRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
IsAvailable: true,
|
IsAvailable: true,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
@@ -54,6 +81,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
|
|
||||||
// expired
|
// expired
|
||||||
resp, err = this.RPC().ACMETaskRPC().CountAllEnabledACMETasks(this.AdminContext(), &pb.CountAllEnabledACMETasksRequest{
|
resp, err = this.RPC().ACMETaskRPC().CountAllEnabledACMETasks(this.AdminContext(), &pb.CountAllEnabledACMETasksRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
IsExpired: true,
|
IsExpired: true,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
@@ -65,6 +93,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
|
|
||||||
// expire in 7 days
|
// expire in 7 days
|
||||||
resp, err = this.RPC().ACMETaskRPC().CountAllEnabledACMETasks(this.AdminContext(), &pb.CountAllEnabledACMETasksRequest{
|
resp, err = this.RPC().ACMETaskRPC().CountAllEnabledACMETasks(this.AdminContext(), &pb.CountAllEnabledACMETasksRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
ExpiringDays: 7,
|
ExpiringDays: 7,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
@@ -76,6 +105,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
|
|
||||||
// expire in 30 days
|
// expire in 30 days
|
||||||
resp, err = this.RPC().ACMETaskRPC().CountAllEnabledACMETasks(this.AdminContext(), &pb.CountAllEnabledACMETasksRequest{
|
resp, err = this.RPC().ACMETaskRPC().CountAllEnabledACMETasks(this.AdminContext(), &pb.CountAllEnabledACMETasksRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
ExpiringDays: 30,
|
ExpiringDays: 30,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
@@ -100,25 +130,51 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
case "":
|
case "":
|
||||||
page = this.NewPage(countAll)
|
page = this.NewPage(countAll)
|
||||||
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{
|
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
Offset: page.Offset,
|
Offset: page.Offset,
|
||||||
Size: page.Size,
|
Size: page.Size,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
case "available":
|
case "available":
|
||||||
page = this.NewPage(countAvailable)
|
page = this.NewPage(countAvailable)
|
||||||
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{IsAvailable: true, Offset: page.Offset, Size: page.Size, Keyword: params.Keyword})
|
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
|
IsAvailable: true,
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
Keyword: params.Keyword,
|
||||||
|
})
|
||||||
case "expired":
|
case "expired":
|
||||||
page = this.NewPage(countExpired)
|
page = this.NewPage(countExpired)
|
||||||
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{IsExpired: true, Offset: page.Offset, Size: page.Size, Keyword: params.Keyword})
|
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
|
IsExpired: true,
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
Keyword: params.Keyword,
|
||||||
|
})
|
||||||
case "7days":
|
case "7days":
|
||||||
page = this.NewPage(count7Days)
|
page = this.NewPage(count7Days)
|
||||||
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{ExpiringDays: 7, Offset: page.Offset, Size: page.Size, Keyword: params.Keyword})
|
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
|
ExpiringDays: 7,
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
Keyword: params.Keyword,
|
||||||
|
})
|
||||||
case "30days":
|
case "30days":
|
||||||
page = this.NewPage(count30Days)
|
page = this.NewPage(count30Days)
|
||||||
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{ExpiringDays: 30, Offset: page.Offset, Size: page.Size, Keyword: params.Keyword})
|
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
|
ExpiringDays: 30,
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
Keyword: params.Keyword,
|
||||||
|
})
|
||||||
default:
|
default:
|
||||||
page = this.NewPage(countAll)
|
page = this.NewPage(countAll)
|
||||||
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{
|
tasksResp, err = this.RPC().ACMETaskRPC().ListEnabledACMETasks(this.AdminContext(), &pb.ListEnabledACMETasksRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
Offset: page.Offset,
|
Offset: page.Offset,
|
||||||
Size: page.Size,
|
Size: page.Size,
|
||||||
@@ -131,7 +187,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
|
|
||||||
this.Data["page"] = page.AsHTML()
|
this.Data["page"] = page.AsHTML()
|
||||||
|
|
||||||
taskMaps := []maps.Map{}
|
var taskMaps = []maps.Map{}
|
||||||
for _, task := range tasksResp.AcmeTasks {
|
for _, task := range tasksResp.AcmeTasks {
|
||||||
if task.AcmeUser == nil {
|
if task.AcmeUser == nil {
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ type RunAction struct {
|
|||||||
func (this *RunAction) RunPost(params struct {
|
func (this *RunAction) RunPost(params struct {
|
||||||
TaskId int64
|
TaskId int64
|
||||||
}) {
|
}) {
|
||||||
|
defer this.CreateLogInfo("执行ACME任务 %d", params.TaskId)
|
||||||
|
|
||||||
runResp, err := this.RPC().ACMETaskRPC().RunACMETask(this.AdminContext(), &pb.RunACMETaskRequest{AcmeTaskId: params.TaskId})
|
runResp, err := this.RPC().ACMETaskRPC().RunACMETask(this.AdminContext(), &pb.RunACMETaskRequest{AcmeTaskId: params.TaskId})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package acme
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserOptionsAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UserOptionsAction) RunPost(params struct {
|
||||||
|
PlatformUserId int64
|
||||||
|
}) {
|
||||||
|
// 获取所有可用的用户
|
||||||
|
usersResp, err := this.RPC().ACMEUserRPC().FindAllACMEUsers(this.AdminContext(), &pb.FindAllACMEUsersRequest{
|
||||||
|
AdminId: 0,
|
||||||
|
UserId: params.PlatformUserId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var userMaps = []maps.Map{}
|
||||||
|
for _, user := range usersResp.AcmeUsers {
|
||||||
|
description := user.Description
|
||||||
|
if len(description) > 0 {
|
||||||
|
description = "(" + description + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
userMaps = append(userMaps, maps.Map{
|
||||||
|
"id": user.Id,
|
||||||
|
"description": description,
|
||||||
|
"email": user.Email,
|
||||||
|
"providerCode": user.AcmeProviderCode,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.Data["users"] = userMaps
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -16,10 +16,30 @@ func (this *CreatePopupAction) Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *CreatePopupAction) RunGet(params struct {
|
func (this *CreatePopupAction) RunGet(params struct {
|
||||||
ProviderCode string
|
PlatformUserId int64
|
||||||
|
ProviderCode string
|
||||||
}) {
|
}) {
|
||||||
|
this.Data["platformUserId"] = params.PlatformUserId
|
||||||
this.Data["providerCode"] = params.ProviderCode
|
this.Data["providerCode"] = params.ProviderCode
|
||||||
|
|
||||||
|
// 平台用户信息
|
||||||
|
this.Data["platformUser"] = nil
|
||||||
|
if params.PlatformUserId > 0 {
|
||||||
|
platformUserResp, err := this.RPC().UserRPC().FindEnabledUser(this.AdminContext(), &pb.FindEnabledUserRequest{UserId: params.PlatformUserId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var platformUser = platformUserResp.User
|
||||||
|
if platformUser != nil {
|
||||||
|
this.Data["platformUser"] = maps.Map{
|
||||||
|
"id": platformUser.Id,
|
||||||
|
"username": platformUser.Username,
|
||||||
|
"fullname": platformUser.Fullname,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 服务商
|
// 服务商
|
||||||
providersResp, err := this.RPC().ACMEProviderRPC().FindAllACMEProviders(this.AdminContext(), &pb.FindAllACMEProvidersRequest{})
|
providersResp, err := this.RPC().ACMEProviderRPC().FindAllACMEProviders(this.AdminContext(), &pb.FindAllACMEProvidersRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -40,10 +60,11 @@ func (this *CreatePopupAction) RunGet(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *CreatePopupAction) RunPost(params struct {
|
func (this *CreatePopupAction) RunPost(params struct {
|
||||||
Email string
|
PlatformUserId int64
|
||||||
ProviderCode string
|
Email string
|
||||||
AccountId int64
|
ProviderCode string
|
||||||
Description string
|
AccountId int64
|
||||||
|
Description string
|
||||||
|
|
||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
CSRF *actionutils.CSRF
|
CSRF *actionutils.CSRF
|
||||||
@@ -85,6 +106,7 @@ func (this *CreatePopupAction) RunPost(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createResp, err := this.RPC().ACMEUserRPC().CreateACMEUser(this.AdminContext(), &pb.CreateACMEUserRequest{
|
createResp, err := this.RPC().ACMEUserRPC().CreateACMEUser(this.AdminContext(), &pb.CreateACMEUserRequest{
|
||||||
|
UserId: params.PlatformUserId,
|
||||||
Email: params.Email,
|
Email: params.Email,
|
||||||
Description: params.Description,
|
Description: params.Description,
|
||||||
AcmeProviderCode: params.ProviderCode,
|
AcmeProviderCode: params.ProviderCode,
|
||||||
|
|||||||
@@ -19,12 +19,37 @@ func (this *IndexAction) Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *IndexAction) RunGet(params struct {
|
func (this *IndexAction) RunGet(params struct {
|
||||||
|
UserId int64
|
||||||
Type string
|
Type string
|
||||||
Keyword string
|
Keyword string
|
||||||
}) {
|
}) {
|
||||||
this.Data["type"] = params.Type
|
this.Data["type"] = params.Type
|
||||||
this.Data["keyword"] = params.Keyword
|
this.Data["keyword"] = params.Keyword
|
||||||
|
|
||||||
|
// 当前用户
|
||||||
|
this.Data["searchingUserId"] = params.UserId
|
||||||
|
var userMap = maps.Map{
|
||||||
|
"id": 0,
|
||||||
|
"username": "",
|
||||||
|
"fullname": "",
|
||||||
|
}
|
||||||
|
if params.UserId > 0 {
|
||||||
|
userResp, err := this.RPC().UserRPC().FindEnabledUser(this.AdminContext(), &pb.FindEnabledUserRequest{UserId: params.UserId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var user = userResp.User
|
||||||
|
if user != nil {
|
||||||
|
userMap = maps.Map{
|
||||||
|
"id": user.Id,
|
||||||
|
"username": user.Username,
|
||||||
|
"fullname": user.Fullname,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Data["user"] = userMap
|
||||||
|
|
||||||
var countAll = int64(0)
|
var countAll = int64(0)
|
||||||
var countCA = int64(0)
|
var countCA = int64(0)
|
||||||
var countAvailable = int64(0)
|
var countAvailable = int64(0)
|
||||||
@@ -36,6 +61,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
{
|
{
|
||||||
// all
|
// all
|
||||||
resp, err := this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
resp, err := this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -46,6 +72,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
|
|
||||||
// CA
|
// CA
|
||||||
resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
IsCA: true,
|
IsCA: true,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
@@ -57,6 +84,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
|
|
||||||
// available
|
// available
|
||||||
resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
IsAvailable: true,
|
IsAvailable: true,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
@@ -68,6 +96,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
|
|
||||||
// expired
|
// expired
|
||||||
resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
IsExpired: true,
|
IsExpired: true,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
@@ -79,6 +108,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
|
|
||||||
// expire in 7 days
|
// expire in 7 days
|
||||||
resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
ExpiringDays: 7,
|
ExpiringDays: 7,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
@@ -90,6 +120,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
|
|
||||||
// expire in 30 days
|
// expire in 30 days
|
||||||
resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
ExpiringDays: 30,
|
ExpiringDays: 30,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
@@ -115,28 +146,60 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
case "":
|
case "":
|
||||||
page = this.NewPage(countAll)
|
page = this.NewPage(countAll)
|
||||||
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{
|
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
Offset: page.Offset,
|
Offset: page.Offset,
|
||||||
Size: page.Size,
|
Size: page.Size,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
})
|
})
|
||||||
case "ca":
|
case "ca":
|
||||||
page = this.NewPage(countCA)
|
page = this.NewPage(countCA)
|
||||||
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{IsCA: true, Offset: page.Offset, Size: page.Size, Keyword: params.Keyword})
|
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
|
IsCA: true,
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
Keyword: params.Keyword,
|
||||||
|
})
|
||||||
case "available":
|
case "available":
|
||||||
page = this.NewPage(countAvailable)
|
page = this.NewPage(countAvailable)
|
||||||
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{IsAvailable: true, Offset: page.Offset, Size: page.Size, Keyword: params.Keyword})
|
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
|
IsAvailable: true,
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
Keyword: params.Keyword,
|
||||||
|
})
|
||||||
case "expired":
|
case "expired":
|
||||||
page = this.NewPage(countExpired)
|
page = this.NewPage(countExpired)
|
||||||
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{IsExpired: true, Offset: page.Offset, Size: page.Size, Keyword: params.Keyword})
|
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
|
IsExpired: true,
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
Keyword: params.Keyword,
|
||||||
|
})
|
||||||
case "7days":
|
case "7days":
|
||||||
page = this.NewPage(count7Days)
|
page = this.NewPage(count7Days)
|
||||||
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{ExpiringDays: 7, Offset: page.Offset, Size: page.Size, Keyword: params.Keyword})
|
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
|
ExpiringDays: 7,
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
Keyword: params.Keyword,
|
||||||
|
})
|
||||||
case "30days":
|
case "30days":
|
||||||
page = this.NewPage(count30Days)
|
page = this.NewPage(count30Days)
|
||||||
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{ExpiringDays: 30, Offset: page.Offset, Size: page.Size, Keyword: params.Keyword})
|
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
|
ExpiringDays: 30,
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
Keyword: params.Keyword,
|
||||||
|
})
|
||||||
default:
|
default:
|
||||||
page = this.NewPage(countAll)
|
page = this.NewPage(countAll)
|
||||||
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{
|
listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{
|
||||||
|
UserId: params.UserId,
|
||||||
Keyword: params.Keyword,
|
Keyword: params.Keyword,
|
||||||
Offset: page.Offset,
|
Offset: page.Offset,
|
||||||
Size: page.Size,
|
Size: page.Size,
|
||||||
@@ -158,7 +221,9 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
var certMaps = []maps.Map{}
|
var certMaps = []maps.Map{}
|
||||||
var nowTime = time.Now().Unix()
|
var nowTime = time.Now().Unix()
|
||||||
for _, certConfig := range certConfigs {
|
for _, certConfig := range certConfigs {
|
||||||
countServersResp, err := this.RPC().ServerRPC().CountAllEnabledServersWithSSLCertId(this.AdminContext(), &pb.CountAllEnabledServersWithSSLCertIdRequest{SslCertId: certConfig.Id})
|
countServersResp, err := this.RPC().ServerRPC().CountAllEnabledServersWithSSLCertId(this.AdminContext(), &pb.CountAllEnabledServersWithSSLCertIdRequest{
|
||||||
|
SslCertId: certConfig.Id,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ func init() {
|
|||||||
Post("/run", new(acme.RunAction)).
|
Post("/run", new(acme.RunAction)).
|
||||||
GetPost("/updateTaskPopup", new(acme.UpdateTaskPopupAction)).
|
GetPost("/updateTaskPopup", new(acme.UpdateTaskPopupAction)).
|
||||||
Post("/deleteTask", new(acme.DeleteTaskAction)).
|
Post("/deleteTask", new(acme.DeleteTaskAction)).
|
||||||
|
Post("/userOptions", new(acme.UserOptionsAction)).
|
||||||
|
|
||||||
// ACME用户
|
// ACME用户
|
||||||
Prefix("/servers/certs/acme/users").
|
Prefix("/servers/certs/acme/users").
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ func (this *SelectPopupAction) RunGet(params struct {
|
|||||||
SelectedCertIds string
|
SelectedCertIds string
|
||||||
Keyword string
|
Keyword string
|
||||||
}) {
|
}) {
|
||||||
|
this.Data["searchingServerId"] = params.ServerId
|
||||||
|
|
||||||
// 服务相关
|
// 服务相关
|
||||||
if params.ServerId > 0 {
|
if params.ServerId > 0 {
|
||||||
serverResp, err := this.RPC().ServerRPC().FindEnabledUserServerBasic(this.AdminContext(), &pb.FindEnabledUserServerBasicRequest{ServerId: params.ServerId})
|
serverResp, err := this.RPC().ServerRPC().FindEnabledUserServerBasic(this.AdminContext(), &pb.FindEnabledUserServerBasicRequest{ServerId: params.ServerId})
|
||||||
@@ -66,7 +68,8 @@ func (this *SelectPopupAction) RunGet(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 用户相关
|
// 用户相关
|
||||||
this.Data["userId"] = params.UserId
|
this.Data["userId"] = params.UserId // 可变
|
||||||
|
this.Data["searchingUserId"] = params.UserId
|
||||||
|
|
||||||
// 域名搜索相关
|
// 域名搜索相关
|
||||||
var url = this.Request.URL.Path
|
var url = this.Request.URL.Path
|
||||||
@@ -82,6 +85,7 @@ func (this *SelectPopupAction) RunGet(params struct {
|
|||||||
if len(searchingDomains) > maxDomains {
|
if len(searchingDomains) > maxDomains {
|
||||||
searchingDomains = searchingDomains[:maxDomains]
|
searchingDomains = searchingDomains[:maxDomains]
|
||||||
}
|
}
|
||||||
|
this.Data["allSearchingDomains"] = params.SearchingDomains
|
||||||
this.Data["searchingDomains"] = searchingDomains
|
this.Data["searchingDomains"] = searchingDomains
|
||||||
|
|
||||||
this.Data["keyword"] = params.Keyword
|
this.Data["keyword"] = params.Keyword
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func KeyFailReason(reasonCode string) string {
|
|||||||
case "requireDomain":
|
case "requireDomain":
|
||||||
return "找不到Key对应的域名"
|
return "找不到Key对应的域名"
|
||||||
case "requireServer":
|
case "requireServer":
|
||||||
return "找不到Key对应的网站服务"
|
return "找不到Key对应的网站"
|
||||||
case "requireUser":
|
case "requireUser":
|
||||||
return "该域名不属于当前用户"
|
return "该域名不属于当前用户"
|
||||||
case "requireClusterId":
|
case "requireClusterId":
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
DefaultDomain string
|
DefaultDomain string
|
||||||
}) {
|
}) {
|
||||||
// 创建日志
|
// 创建日志
|
||||||
defer this.CreateLog(oplogs.LevelInfo, "保存网站服务全局配置")
|
defer this.CreateLog(oplogs.LevelInfo, "保存网站全局配置")
|
||||||
|
|
||||||
if len(params.GlobalConfigJSON) == 0 {
|
if len(params.GlobalConfigJSON) == 0 {
|
||||||
this.Fail("错误的配置信息,请刷新当前页面后重试")
|
this.Fail("错误的配置信息,请刷新当前页面后重试")
|
||||||
|
|||||||
@@ -238,7 +238,8 @@ func (this *CreateAction) RunPost(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sslPolicyIdResp, err := this.RPC().SSLPolicyRPC().CreateSSLPolicy(this.AdminContext(), &pb.CreateSSLPolicyRequest{
|
sslPolicyIdResp, err := this.RPC().SSLPolicyRPC().CreateSSLPolicy(this.AdminContext(), &pb.CreateSSLPolicyRequest{
|
||||||
Http2Enabled: false, // 默认值
|
Http2Enabled: false, // 默认值
|
||||||
|
Http3Enabled: false,
|
||||||
MinVersion: "TLS 1.1", // 默认值
|
MinVersion: "TLS 1.1", // 默认值
|
||||||
SslCertsJSON: certRefsJSON,
|
SslCertsJSON: certRefsJSON,
|
||||||
HstsJSON: nil,
|
HstsJSON: nil,
|
||||||
@@ -387,7 +388,7 @@ func (this *CreateAction) RunPost(params struct {
|
|||||||
AdminId: this.AdminId(),
|
AdminId: this.AdminId(),
|
||||||
Type: params.ServerType,
|
Type: params.ServerType,
|
||||||
Name: params.Name,
|
Name: params.Name,
|
||||||
ServerNamesJSON: params.ServerNames,
|
ServerNamesJSON: params.ServerNames,
|
||||||
Description: params.Description,
|
Description: params.Description,
|
||||||
NodeClusterId: clusterId,
|
NodeClusterId: clusterId,
|
||||||
IncludeNodesJSON: includeNodesJSON,
|
IncludeNodesJSON: includeNodesJSON,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func (this *CreatePopupAction) RunPost(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建日志
|
// 创建日志
|
||||||
defer this.CreateLog(oplogs.LevelInfo, "创建服务分组 %d", createResp.ServerGroupId)
|
defer this.CreateLog(oplogs.LevelInfo, "创建网站分组 %d", createResp.ServerGroupId)
|
||||||
|
|
||||||
this.Success()
|
this.Success()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func (this *DeleteAction) RunPost(params struct {
|
|||||||
GroupId int64
|
GroupId int64
|
||||||
}) {
|
}) {
|
||||||
// 创建日志
|
// 创建日志
|
||||||
defer this.CreateLog(oplogs.LevelInfo, "删除代理服务分组 %d", params.GroupId)
|
defer this.CreateLog(oplogs.LevelInfo, "删除代理网站分组 %d", params.GroupId)
|
||||||
|
|
||||||
// 检查是否正在使用
|
// 检查是否正在使用
|
||||||
countResp, err := this.RPC().ServerRPC().CountAllEnabledServersWithServerGroupId(this.AdminContext(), &pb.CountAllEnabledServersWithServerGroupIdRequest{ServerGroupId: params.GroupId})
|
countResp, err := this.RPC().ServerRPC().CountAllEnabledServersWithServerGroupId(this.AdminContext(), &pb.CountAllEnabledServersWithServerGroupIdRequest{ServerGroupId: params.GroupId})
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
var m = maps.Map{
|
var m = maps.Map{
|
||||||
"id": originConfig.Id,
|
"id": originConfig.Id,
|
||||||
"weight": originConfig.Weight,
|
"weight": originConfig.Weight,
|
||||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
"addr": originConfig.AddrSummary(),
|
||||||
|
"isOSS": originConfig.IsOSS(),
|
||||||
"name": originConfig.Name,
|
"name": originConfig.Name,
|
||||||
"isOn": originConfig.IsOn,
|
"isOn": originConfig.IsOn,
|
||||||
"domains": originConfig.Domains,
|
"domains": originConfig.Domains,
|
||||||
@@ -76,7 +77,8 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
var m = maps.Map{
|
var m = maps.Map{
|
||||||
"id": originConfig.Id,
|
"id": originConfig.Id,
|
||||||
"weight": originConfig.Weight,
|
"weight": originConfig.Weight,
|
||||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
"addr": originConfig.AddrSummary(),
|
||||||
|
"isOSS": originConfig.IsOSS(),
|
||||||
"name": originConfig.Name,
|
"name": originConfig.Name,
|
||||||
"isOn": originConfig.IsOn,
|
"isOn": originConfig.IsOn,
|
||||||
"domains": originConfig.Domains,
|
"domains": originConfig.Domains,
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
m := maps.Map{
|
m := maps.Map{
|
||||||
"id": originConfig.Id,
|
"id": originConfig.Id,
|
||||||
"weight": originConfig.Weight,
|
"weight": originConfig.Weight,
|
||||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
"addr": originConfig.AddrSummary(),
|
||||||
|
"isOSS": originConfig.IsOSS(),
|
||||||
"name": originConfig.Name,
|
"name": originConfig.Name,
|
||||||
"isOn": originConfig.IsOn,
|
"isOn": originConfig.IsOn,
|
||||||
"domains": originConfig.Domains,
|
"domains": originConfig.Domains,
|
||||||
@@ -76,7 +77,8 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
m := maps.Map{
|
m := maps.Map{
|
||||||
"id": originConfig.Id,
|
"id": originConfig.Id,
|
||||||
"weight": originConfig.Weight,
|
"weight": originConfig.Weight,
|
||||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
"addr": originConfig.AddrSummary(),
|
||||||
|
"isOSS": originConfig.IsOSS(),
|
||||||
"name": originConfig.Name,
|
"name": originConfig.Name,
|
||||||
"isOn": originConfig.IsOn,
|
"isOn": originConfig.IsOn,
|
||||||
"domains": originConfig.Domains,
|
"domains": originConfig.Domains,
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
var m = maps.Map{
|
var m = maps.Map{
|
||||||
"id": originConfig.Id,
|
"id": originConfig.Id,
|
||||||
"weight": originConfig.Weight,
|
"weight": originConfig.Weight,
|
||||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
"addr": originConfig.AddrSummary(),
|
||||||
|
"isOSS": originConfig.IsOSS(),
|
||||||
"name": originConfig.Name,
|
"name": originConfig.Name,
|
||||||
"isOn": originConfig.IsOn,
|
"isOn": originConfig.IsOn,
|
||||||
"domains": originConfig.Domains,
|
"domains": originConfig.Domains,
|
||||||
@@ -76,7 +77,8 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
var m = maps.Map{
|
var m = maps.Map{
|
||||||
"id": originConfig.Id,
|
"id": originConfig.Id,
|
||||||
"weight": originConfig.Weight,
|
"weight": originConfig.Weight,
|
||||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
"addr": originConfig.AddrSummary(),
|
||||||
|
"isOSS": originConfig.IsOSS(),
|
||||||
"name": originConfig.Name,
|
"name": originConfig.Name,
|
||||||
"isOn": originConfig.IsOn,
|
"isOn": originConfig.IsOn,
|
||||||
"domains": originConfig.Domains,
|
"domains": originConfig.Domains,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func (this *UpdateAction) RunPost(params struct {
|
|||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
}) {
|
}) {
|
||||||
// 创建日志
|
// 创建日志
|
||||||
defer this.CreateLog(oplogs.LevelInfo, "修改代理服务分组 %d", params.GroupId)
|
defer this.CreateLog(oplogs.LevelInfo, "修改网站分组 %d", params.GroupId)
|
||||||
|
|
||||||
params.Must.
|
params.Must.
|
||||||
Field("name", params.Name).
|
Field("name", params.Name).
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func (this *SortAction) RunPost(params struct {
|
|||||||
GroupIds []int64
|
GroupIds []int64
|
||||||
}) {
|
}) {
|
||||||
// 创建日志
|
// 创建日志
|
||||||
defer this.CreateLog(oplogs.LevelInfo, "修改服务分组排序")
|
defer this.CreateLog(oplogs.LevelInfo, "修改网站分组排序")
|
||||||
|
|
||||||
_, err := this.RPC().ServerGroupRPC().UpdateServerGroupOrders(this.AdminContext(), &pb.UpdateServerGroupOrdersRequest{ServerGroupIds: params.GroupIds})
|
_, err := this.RPC().ServerGroupRPC().UpdateServerGroupOrders(this.AdminContext(), &pb.UpdateServerGroupOrdersRequest{ServerGroupIds: params.GroupIds})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ func (this *IndexAction) Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *IndexAction) RunGet(params struct {
|
func (this *IndexAction) RunGet(params struct {
|
||||||
|
Ip string
|
||||||
Keyword string
|
Keyword string
|
||||||
GlobalOnly bool
|
GlobalOnly bool
|
||||||
Unread bool
|
Unread bool
|
||||||
@@ -40,6 +41,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
Unread: true,
|
Unread: true,
|
||||||
EventLevel: params.EventLevel,
|
EventLevel: params.EventLevel,
|
||||||
ListType: params.ListType,
|
ListType: params.ListType,
|
||||||
|
Ip: params.Ip,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
@@ -53,6 +55,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
Unread: params.Unread,
|
Unread: params.Unread,
|
||||||
EventLevel: params.EventLevel,
|
EventLevel: params.EventLevel,
|
||||||
ListType: params.ListType,
|
ListType: params.ListType,
|
||||||
|
Ip: params.Ip,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
@@ -68,6 +71,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
Unread: params.Unread,
|
Unread: params.Unread,
|
||||||
EventLevel: params.EventLevel,
|
EventLevel: params.EventLevel,
|
||||||
ListType: params.ListType,
|
ListType: params.ListType,
|
||||||
|
Ip: params.Ip,
|
||||||
Offset: page.Offset,
|
Offset: page.Offset,
|
||||||
Size: page.Size,
|
Size: page.Size,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -45,14 +45,14 @@ func (this *CreateDeletePopupAction) RunPost(params struct {
|
|||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
policyConfig := &shared.HTTPHeaderPolicy{}
|
var policyConfig = &shared.HTTPHeaderPolicy{}
|
||||||
err = json.Unmarshal(policyConfigResp.HttpHeaderPolicyJSON, policyConfig)
|
err = json.Unmarshal(policyConfigResp.HttpHeaderPolicyJSON, policyConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteHeaders := policyConfig.DeleteHeaders
|
var deleteHeaders = policyConfig.DeleteHeaders
|
||||||
deleteHeaders = append(deleteHeaders, params.Name)
|
deleteHeaders = append(deleteHeaders, params.Name)
|
||||||
_, err = this.RPC().HTTPHeaderPolicyRPC().UpdateHTTPHeaderPolicyDeletingHeaders(this.AdminContext(), &pb.UpdateHTTPHeaderPolicyDeletingHeadersRequest{
|
_, err = this.RPC().HTTPHeaderPolicyRPC().UpdateHTTPHeaderPolicyDeletingHeaders(this.AdminContext(), &pb.UpdateHTTPHeaderPolicyDeletingHeadersRequest{
|
||||||
HttpHeaderPolicyId: params.HeaderPolicyId,
|
HttpHeaderPolicyId: params.HeaderPolicyId,
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package headers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateNonStandardPopupAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreateNonStandardPopupAction) Init() {
|
||||||
|
this.Nav("", "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreateNonStandardPopupAction) RunGet(params struct {
|
||||||
|
HeaderPolicyId int64
|
||||||
|
Type string
|
||||||
|
}) {
|
||||||
|
this.Data["headerPolicyId"] = params.HeaderPolicyId
|
||||||
|
this.Data["type"] = params.Type
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreateNonStandardPopupAction) RunPost(params struct {
|
||||||
|
HeaderPolicyId int64
|
||||||
|
Name string
|
||||||
|
|
||||||
|
Must *actions.Must
|
||||||
|
}) {
|
||||||
|
// 日志
|
||||||
|
defer this.CreateLog(oplogs.LevelInfo, "添加非标的Header HeaderPolicyId: %d, Name: %s", params.HeaderPolicyId, params.Name)
|
||||||
|
|
||||||
|
params.Must.
|
||||||
|
Field("name", params.Name).
|
||||||
|
Require("名称不能为空")
|
||||||
|
|
||||||
|
policyConfigResp, err := this.RPC().HTTPHeaderPolicyRPC().FindEnabledHTTPHeaderPolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPHeaderPolicyConfigRequest{HttpHeaderPolicyId: params.HeaderPolicyId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var policyConfig = &shared.HTTPHeaderPolicy{}
|
||||||
|
err = json.Unmarshal(policyConfigResp.HttpHeaderPolicyJSON, policyConfig)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var nonStandardHeaders = policyConfig.NonStandardHeaders
|
||||||
|
nonStandardHeaders = append(nonStandardHeaders, params.Name)
|
||||||
|
_, err = this.RPC().HTTPHeaderPolicyRPC().UpdateHTTPHeaderPolicyNonStandardHeaders(this.AdminContext(), &pb.UpdateHTTPHeaderPolicyNonStandardHeadersRequest{
|
||||||
|
HttpHeaderPolicyId: params.HeaderPolicyId,
|
||||||
|
HeaderNames: nonStandardHeaders,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -17,22 +17,22 @@ func (this *DeleteDeletingHeaderAction) RunPost(params struct {
|
|||||||
HeaderName string
|
HeaderName string
|
||||||
}) {
|
}) {
|
||||||
// 日志
|
// 日志
|
||||||
defer this.CreateLog(oplogs.LevelInfo, "删除需要删除的请求Header,HeaderPolicyId:%d, HeaderName:%s", params.HeaderPolicyId, params.HeaderName)
|
defer this.CreateLog(oplogs.LevelInfo, "删除需要删除的Header,HeaderPolicyId:%d, HeaderName:%s", params.HeaderPolicyId, params.HeaderName)
|
||||||
|
|
||||||
policyConfigResp, err := this.RPC().HTTPHeaderPolicyRPC().FindEnabledHTTPHeaderPolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPHeaderPolicyConfigRequest{HttpHeaderPolicyId: params.HeaderPolicyId})
|
policyConfigResp, err := this.RPC().HTTPHeaderPolicyRPC().FindEnabledHTTPHeaderPolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPHeaderPolicyConfigRequest{HttpHeaderPolicyId: params.HeaderPolicyId})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
policyConfigJSON := policyConfigResp.HttpHeaderPolicyJSON
|
var policyConfigJSON = policyConfigResp.HttpHeaderPolicyJSON
|
||||||
policyConfig := &shared.HTTPHeaderPolicy{}
|
var policyConfig = &shared.HTTPHeaderPolicy{}
|
||||||
err = json.Unmarshal(policyConfigJSON, policyConfig)
|
err = json.Unmarshal(policyConfigJSON, policyConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
headerNames := []string{}
|
var headerNames = []string{}
|
||||||
for _, h := range policyConfig.DeleteHeaders {
|
for _, h := range policyConfig.DeleteHeaders {
|
||||||
if h == params.HeaderName {
|
if h == params.HeaderName {
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package headers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeleteNonStandardHeaderAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *DeleteNonStandardHeaderAction) RunPost(params struct {
|
||||||
|
HeaderPolicyId int64
|
||||||
|
HeaderName string
|
||||||
|
}) {
|
||||||
|
// 日志
|
||||||
|
defer this.CreateLog(oplogs.LevelInfo, "删除需要非标的Header,HeaderPolicyId:%d, HeaderName:%s", params.HeaderPolicyId, params.HeaderName)
|
||||||
|
|
||||||
|
policyConfigResp, err := this.RPC().HTTPHeaderPolicyRPC().FindEnabledHTTPHeaderPolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPHeaderPolicyConfigRequest{HttpHeaderPolicyId: params.HeaderPolicyId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var policyConfigJSON = policyConfigResp.HttpHeaderPolicyJSON
|
||||||
|
var policyConfig = &shared.HTTPHeaderPolicy{}
|
||||||
|
err = json.Unmarshal(policyConfigJSON, policyConfig)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var headerNames = []string{}
|
||||||
|
for _, h := range policyConfig.NonStandardHeaders {
|
||||||
|
if h == params.HeaderName {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
headerNames = append(headerNames, h)
|
||||||
|
}
|
||||||
|
_, err = this.RPC().HTTPHeaderPolicyRPC().UpdateHTTPHeaderPolicyNonStandardHeaders(this.AdminContext(), &pb.UpdateHTTPHeaderPolicyNonStandardHeadersRequest{
|
||||||
|
HttpHeaderPolicyId: params.HeaderPolicyId,
|
||||||
|
HeaderNames: headerNames,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -18,6 +18,8 @@ func init() {
|
|||||||
GetPost("/updateSetPopup", new(UpdateSetPopupAction)).
|
GetPost("/updateSetPopup", new(UpdateSetPopupAction)).
|
||||||
GetPost("/createDeletePopup", new(CreateDeletePopupAction)).
|
GetPost("/createDeletePopup", new(CreateDeletePopupAction)).
|
||||||
Post("/deleteDeletingHeader", new(DeleteDeletingHeaderAction)).
|
Post("/deleteDeletingHeader", new(DeleteDeletingHeaderAction)).
|
||||||
|
GetPost("/createNonStandardPopup", new(CreateNonStandardPopupAction)).
|
||||||
|
Post("/deleteNonStandardHeader", new(DeleteNonStandardHeaderAction)).
|
||||||
Post("/delete", new(DeleteAction)).
|
Post("/delete", new(DeleteAction)).
|
||||||
GetPost("/updateCORSPopup", new(UpdateCORSPopupAction)).
|
GetPost("/updateCORSPopup", new(UpdateCORSPopupAction)).
|
||||||
EndAll()
|
EndAll()
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func (this *UpdateCORSPopupAction) RunPost(params struct {
|
|||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
CSRF *actionutils.CSRF
|
CSRF *actionutils.CSRF
|
||||||
}) {
|
}) {
|
||||||
var config = &shared.HTTPCORSHeaderConfig{}
|
var config = shared.NewHTTPCORSHeaderConfig()
|
||||||
err := json.Unmarshal(params.CorsJSON, config)
|
err := json.Unmarshal(params.CorsJSON, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.Fail("配置校验失败:" + err.Error())
|
this.Fail("配置校验失败:" + err.Error())
|
||||||
|
|||||||
@@ -85,11 +85,23 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 当前集群是否支持HTTP/3
|
||||||
|
if server.NodeCluster == nil {
|
||||||
|
this.ErrorPage(errors.New("no node cluster for the server"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
supportsHTTP3, err := this.checkSupportsHTTP3(server.NodeCluster.Id)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
this.Data["serverType"] = server.Type
|
this.Data["serverType"] = server.Type
|
||||||
this.Data["httpsConfig"] = maps.Map{
|
this.Data["httpsConfig"] = maps.Map{
|
||||||
"isOn": httpsConfig.IsOn,
|
"isOn": httpsConfig.IsOn,
|
||||||
"addresses": httpsConfig.Listen,
|
"addresses": httpsConfig.Listen,
|
||||||
"sslPolicy": sslPolicy,
|
"sslPolicy": sslPolicy,
|
||||||
|
"supportsHTTP3": supportsHTTP3,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
@@ -175,6 +187,7 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
_, err := this.RPC().SSLPolicyRPC().UpdateSSLPolicy(this.AdminContext(), &pb.UpdateSSLPolicyRequest{
|
_, err := this.RPC().SSLPolicyRPC().UpdateSSLPolicy(this.AdminContext(), &pb.UpdateSSLPolicyRequest{
|
||||||
SslPolicyId: sslPolicyId,
|
SslPolicyId: sslPolicyId,
|
||||||
Http2Enabled: sslPolicy.HTTP2Enabled,
|
Http2Enabled: sslPolicy.HTTP2Enabled,
|
||||||
|
Http3Enabled: sslPolicy.HTTP3Enabled,
|
||||||
MinVersion: sslPolicy.MinVersion,
|
MinVersion: sslPolicy.MinVersion,
|
||||||
SslCertsJSON: certsJSON,
|
SslCertsJSON: certsJSON,
|
||||||
HstsJSON: hstsJSON,
|
HstsJSON: hstsJSON,
|
||||||
@@ -191,6 +204,7 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
} else {
|
} else {
|
||||||
resp, err := this.RPC().SSLPolicyRPC().CreateSSLPolicy(this.AdminContext(), &pb.CreateSSLPolicyRequest{
|
resp, err := this.RPC().SSLPolicyRPC().CreateSSLPolicy(this.AdminContext(), &pb.CreateSSLPolicyRequest{
|
||||||
Http2Enabled: sslPolicy.HTTP2Enabled,
|
Http2Enabled: sslPolicy.HTTP2Enabled,
|
||||||
|
Http3Enabled: sslPolicy.HTTP3Enabled,
|
||||||
MinVersion: sslPolicy.MinVersion,
|
MinVersion: sslPolicy.MinVersion,
|
||||||
SslCertsJSON: certsJSON,
|
SslCertsJSON: certsJSON,
|
||||||
HstsJSON: hstsJSON,
|
HstsJSON: hstsJSON,
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package https
|
||||||
|
|
||||||
|
func (this *IndexAction) checkSupportsHTTP3(clusterId int64) (bool, error) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
@@ -38,6 +38,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
AllowEmpty: true,
|
AllowEmpty: true,
|
||||||
AllowSameDomain: true,
|
AllowSameDomain: true,
|
||||||
AllowDomains: nil,
|
AllowDomains: nil,
|
||||||
|
CheckOrigin: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
var m = maps.Map{
|
var m = maps.Map{
|
||||||
"id": originConfig.Id,
|
"id": originConfig.Id,
|
||||||
"weight": originConfig.Weight,
|
"weight": originConfig.Weight,
|
||||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
"addr": originConfig.AddrSummary(),
|
||||||
|
"isOSS": originConfig.IsOSS(),
|
||||||
"name": originConfig.Name,
|
"name": originConfig.Name,
|
||||||
"isOn": originConfig.IsOn,
|
"isOn": originConfig.IsOn,
|
||||||
"domains": originConfig.Domains,
|
"domains": originConfig.Domains,
|
||||||
@@ -77,7 +78,8 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
var m = maps.Map{
|
var m = maps.Map{
|
||||||
"id": originConfig.Id,
|
"id": originConfig.Id,
|
||||||
"weight": originConfig.Weight,
|
"weight": originConfig.Weight,
|
||||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
"addr": originConfig.AddrSummary(),
|
||||||
|
"isOSS": originConfig.IsOSS(),
|
||||||
"name": originConfig.Name,
|
"name": originConfig.Name,
|
||||||
"isOn": originConfig.IsOn,
|
"isOn": originConfig.IsOn,
|
||||||
"domains": originConfig.Domains,
|
"domains": originConfig.Domains,
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ func (this *AddPopupAction) RunGet(params struct {
|
|||||||
// 是否为HTTP
|
// 是否为HTTP
|
||||||
this.Data["isHTTP"] = serverType == "httpProxy" || serverType == "httpWeb"
|
this.Data["isHTTP"] = serverType == "httpProxy" || serverType == "httpWeb"
|
||||||
|
|
||||||
|
// OSS
|
||||||
|
this.getOSSHook()
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,104 +79,142 @@ func (this *AddPopupAction) RunPost(params struct {
|
|||||||
|
|
||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
}) {
|
}) {
|
||||||
params.Must.
|
ossConfig, goNext, err := this.postOSSHook(params.Protocol)
|
||||||
Field("addr", params.Addr).
|
|
||||||
Require("请输入源站地址")
|
|
||||||
|
|
||||||
var addr = params.Addr
|
|
||||||
|
|
||||||
// 是否是完整的地址
|
|
||||||
if (params.Protocol == "http" || params.Protocol == "https") && regexp.MustCompile(`^(http|https)://`).MatchString(addr) {
|
|
||||||
u, err := url.Parse(addr)
|
|
||||||
if err == nil {
|
|
||||||
addr = u.Host
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addr = strings.ReplaceAll(addr, ":", ":")
|
|
||||||
addr = regexp.MustCompile(`\s+`).ReplaceAllString(addr, "")
|
|
||||||
var portIndex = strings.LastIndex(addr, ":")
|
|
||||||
if portIndex < 0 {
|
|
||||||
if params.Protocol == "http" {
|
|
||||||
addr += ":80"
|
|
||||||
} else if params.Protocol == "https" {
|
|
||||||
addr += ":443"
|
|
||||||
} else {
|
|
||||||
this.FailField("addr", "源站地址中需要带有端口")
|
|
||||||
}
|
|
||||||
portIndex = strings.LastIndex(addr, ":")
|
|
||||||
}
|
|
||||||
var host = addr[:portIndex]
|
|
||||||
var port = addr[portIndex+1:]
|
|
||||||
|
|
||||||
// 检查端口号
|
|
||||||
if port == "0" {
|
|
||||||
this.FailField("addr", "源站端口号不能为0")
|
|
||||||
}
|
|
||||||
if !configutils.HasVariables(port) {
|
|
||||||
// 必须是整数
|
|
||||||
if !regexp.MustCompile(`^\d+$`).MatchString(port) {
|
|
||||||
this.FailField("addr", "源站端口号只能为整数")
|
|
||||||
}
|
|
||||||
var portInt = types.Int(port)
|
|
||||||
if portInt == 0 {
|
|
||||||
this.FailField("addr", "源站端口号不能为0")
|
|
||||||
}
|
|
||||||
if portInt > 65535 {
|
|
||||||
this.FailField("addr", "源站端口号不能大于65535")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
connTimeoutJSON, err := (&shared.TimeDuration{
|
|
||||||
Count: int64(params.ConnTimeout),
|
|
||||||
Unit: shared.TimeDurationUnitSecond,
|
|
||||||
}).AsJSON()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if !goNext {
|
||||||
readTimeoutJSON, err := (&shared.TimeDuration{
|
|
||||||
Count: int64(params.ReadTimeout),
|
|
||||||
Unit: shared.TimeDurationUnitSecond,
|
|
||||||
}).AsJSON()
|
|
||||||
if err != nil {
|
|
||||||
this.ErrorPage(err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
idleTimeoutJSON, err := (&shared.TimeDuration{
|
// 初始化
|
||||||
Count: int64(params.IdleTimeout),
|
var pbAddr = &pb.NetworkAddress{
|
||||||
Unit: shared.TimeDurationUnitSecond,
|
Protocol: params.Protocol,
|
||||||
}).AsJSON()
|
|
||||||
if err != nil {
|
|
||||||
this.ErrorPage(err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
var connTimeoutJSON []byte
|
||||||
|
var readTimeoutJSON []byte
|
||||||
|
var idleTimeoutJSON []byte
|
||||||
|
var certRefJSON []byte
|
||||||
|
|
||||||
// 证书
|
var ossJSON []byte = nil
|
||||||
var certIds = []int64{}
|
if ossConfig != nil { // OSS
|
||||||
if len(params.CertIdsJSON) > 0 {
|
ossJSON, err = json.Marshal(ossConfig)
|
||||||
err = json.Unmarshal(params.CertIdsJSON, &certIds)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
err = ossConfig.Init()
|
||||||
var certRefJSON []byte
|
if err != nil {
|
||||||
if len(certIds) > 0 {
|
this.Fail("校验OSS配置时出错:" + err.Error())
|
||||||
var certId = certIds[0]
|
return
|
||||||
if certId > 0 {
|
}
|
||||||
var certRef = &sslconfigs.SSLCertRef{
|
} else { // 普通源站
|
||||||
IsOn: true,
|
params.Must.
|
||||||
CertId: certId,
|
Field("addr", params.Addr).
|
||||||
|
Require("请输入源站地址")
|
||||||
|
|
||||||
|
var addr = params.Addr
|
||||||
|
|
||||||
|
// 是否是完整的地址
|
||||||
|
if (params.Protocol == "http" || params.Protocol == "https") && regexp.MustCompile(`^(http|https)://`).MatchString(addr) {
|
||||||
|
u, err := url.Parse(addr)
|
||||||
|
if err == nil {
|
||||||
|
addr = u.Host
|
||||||
}
|
}
|
||||||
certRefJSON, err = json.Marshal(certRef)
|
}
|
||||||
|
|
||||||
|
addr = strings.ReplaceAll(addr, ":", ":")
|
||||||
|
addr = regexp.MustCompile(`\s+`).ReplaceAllString(addr, "")
|
||||||
|
var portIndex = strings.LastIndex(addr, ":")
|
||||||
|
if portIndex < 0 {
|
||||||
|
if params.Protocol == "http" {
|
||||||
|
addr += ":80"
|
||||||
|
} else if params.Protocol == "https" {
|
||||||
|
addr += ":443"
|
||||||
|
} else {
|
||||||
|
this.FailField("addr", "源站地址中需要带有端口")
|
||||||
|
}
|
||||||
|
portIndex = strings.LastIndex(addr, ":")
|
||||||
|
}
|
||||||
|
var host = addr[:portIndex]
|
||||||
|
var port = addr[portIndex+1:]
|
||||||
|
|
||||||
|
// 检查端口号
|
||||||
|
if port == "0" {
|
||||||
|
this.FailField("addr", "源站端口号不能为0")
|
||||||
|
}
|
||||||
|
if !configutils.HasVariables(port) {
|
||||||
|
// 必须是整数
|
||||||
|
if !regexp.MustCompile(`^\d+$`).MatchString(port) {
|
||||||
|
this.FailField("addr", "源站端口号只能为整数")
|
||||||
|
}
|
||||||
|
var portInt = types.Int(port)
|
||||||
|
if portInt == 0 {
|
||||||
|
this.FailField("addr", "源站端口号不能为0")
|
||||||
|
}
|
||||||
|
if portInt > 65535 {
|
||||||
|
this.FailField("addr", "源站端口号不能大于65535")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connTimeoutJSON, err = (&shared.TimeDuration{
|
||||||
|
Count: int64(params.ConnTimeout),
|
||||||
|
Unit: shared.TimeDurationUnitSecond,
|
||||||
|
}).AsJSON()
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
readTimeoutJSON, err = (&shared.TimeDuration{
|
||||||
|
Count: int64(params.ReadTimeout),
|
||||||
|
Unit: shared.TimeDurationUnitSecond,
|
||||||
|
}).AsJSON()
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
idleTimeoutJSON, err = (&shared.TimeDuration{
|
||||||
|
Count: int64(params.IdleTimeout),
|
||||||
|
Unit: shared.TimeDurationUnitSecond,
|
||||||
|
}).AsJSON()
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 证书
|
||||||
|
var certIds = []int64{}
|
||||||
|
if len(params.CertIdsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(params.CertIdsJSON, &certIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(certIds) > 0 {
|
||||||
|
var certId = certIds[0]
|
||||||
|
if certId > 0 {
|
||||||
|
var certRef = &sslconfigs.SSLCertRef{
|
||||||
|
IsOn: true,
|
||||||
|
CertId: certId,
|
||||||
|
}
|
||||||
|
certRefJSON, err = json.Marshal(certRef)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pbAddr = &pb.NetworkAddress{
|
||||||
|
Protocol: params.Protocol,
|
||||||
|
Host: host,
|
||||||
|
PortRange: port,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 专属域名
|
// 专属域名
|
||||||
@@ -192,12 +233,9 @@ func (this *AddPopupAction) RunPost(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createResp, err := this.RPC().OriginRPC().CreateOrigin(this.AdminContext(), &pb.CreateOriginRequest{
|
createResp, err := this.RPC().OriginRPC().CreateOrigin(this.AdminContext(), &pb.CreateOriginRequest{
|
||||||
Name: params.Name,
|
Name: params.Name,
|
||||||
Addr: &pb.NetworkAddress{
|
Addr: pbAddr,
|
||||||
Protocol: params.Protocol,
|
OssJSON: ossJSON,
|
||||||
Host: host,
|
|
||||||
PortRange: port,
|
|
||||||
},
|
|
||||||
Description: params.Description,
|
Description: params.Description,
|
||||||
Weight: params.Weight,
|
Weight: params.Weight,
|
||||||
IsOn: params.IsOn,
|
IsOn: params.IsOn,
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package origins
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ossconfigs"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this *AddPopupAction) getOSSHook() {
|
||||||
|
this.Data["ossTypes"] = []maps.Map{}
|
||||||
|
this.Data["ossBucketParams"] = []maps.Map{}
|
||||||
|
this.Data["ossForm"] = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *AddPopupAction) postOSSHook(protocol string) (config *ossconfigs.OSSConfig, goNext bool, err error) {
|
||||||
|
goNext = true
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -94,10 +94,14 @@ func (this *UpdatePopupAction) RunGet(params struct {
|
|||||||
config.Cert.KeyData = nil
|
config.Cert.KeyData = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var addr = ""
|
||||||
|
if len(config.Addr.Host) > 0 && len(config.Addr.PortRange) > 0 {
|
||||||
|
addr = config.Addr.Host + ":" + config.Addr.PortRange
|
||||||
|
}
|
||||||
this.Data["origin"] = maps.Map{
|
this.Data["origin"] = maps.Map{
|
||||||
"id": config.Id,
|
"id": config.Id,
|
||||||
"protocol": config.Addr.Protocol,
|
"protocol": config.Addr.Protocol,
|
||||||
"addr": config.Addr.Host + ":" + config.Addr.PortRange,
|
"addr": addr,
|
||||||
"weight": config.Weight,
|
"weight": config.Weight,
|
||||||
"name": config.Name,
|
"name": config.Name,
|
||||||
"description": config.Description,
|
"description": config.Description,
|
||||||
@@ -111,8 +115,12 @@ func (this *UpdatePopupAction) RunGet(params struct {
|
|||||||
"domains": config.Domains,
|
"domains": config.Domains,
|
||||||
"host": config.RequestHost,
|
"host": config.RequestHost,
|
||||||
"followPort": config.FollowPort,
|
"followPort": config.FollowPort,
|
||||||
|
"oss": config.OSS,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OSS
|
||||||
|
this.getOSSHook()
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,103 +151,144 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
|||||||
|
|
||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
}) {
|
}) {
|
||||||
params.Must.
|
ossConfig, goNext, err := this.postOSSHook(params.Protocol)
|
||||||
Field("addr", params.Addr).
|
|
||||||
Require("请输入源站地址")
|
|
||||||
|
|
||||||
var addr = params.Addr
|
|
||||||
|
|
||||||
// 是否是完整的地址
|
|
||||||
if (params.Protocol == "http" || params.Protocol == "https") && regexp.MustCompile(`^(http|https)://`).MatchString(addr) {
|
|
||||||
u, err := url.Parse(addr)
|
|
||||||
if err == nil {
|
|
||||||
addr = u.Host
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addr = strings.ReplaceAll(addr, ":", ":")
|
|
||||||
addr = regexp.MustCompile(`\s+`).ReplaceAllString(addr, "")
|
|
||||||
portIndex := strings.LastIndex(addr, ":")
|
|
||||||
if portIndex < 0 {
|
|
||||||
if params.Protocol == "http" {
|
|
||||||
addr += ":80"
|
|
||||||
} else if params.Protocol == "https" {
|
|
||||||
addr += ":443"
|
|
||||||
} else {
|
|
||||||
this.FailField("addr", "源站地址中需要带有端口")
|
|
||||||
}
|
|
||||||
portIndex = strings.LastIndex(addr, ":")
|
|
||||||
}
|
|
||||||
var host = addr[:portIndex]
|
|
||||||
var port = addr[portIndex+1:]
|
|
||||||
// 检查端口号
|
|
||||||
if port == "0" {
|
|
||||||
this.FailField("addr", "源站端口号不能为0")
|
|
||||||
}
|
|
||||||
if !configutils.HasVariables(port) {
|
|
||||||
// 必须是整数
|
|
||||||
if !regexp.MustCompile(`^\d+$`).MatchString(port) {
|
|
||||||
this.FailField("addr", "源站端口号只能为整数")
|
|
||||||
}
|
|
||||||
var portInt = types.Int(port)
|
|
||||||
if portInt == 0 {
|
|
||||||
this.FailField("addr", "源站端口号不能为0")
|
|
||||||
}
|
|
||||||
if portInt > 65535 {
|
|
||||||
this.FailField("addr", "源站端口号不能大于65535")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
connTimeoutJSON, err := (&shared.TimeDuration{
|
|
||||||
Count: int64(params.ConnTimeout),
|
|
||||||
Unit: shared.TimeDurationUnitSecond,
|
|
||||||
}).AsJSON()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if !goNext {
|
||||||
readTimeoutJSON, err := (&shared.TimeDuration{
|
|
||||||
Count: int64(params.ReadTimeout),
|
|
||||||
Unit: shared.TimeDurationUnitSecond,
|
|
||||||
}).AsJSON()
|
|
||||||
if err != nil {
|
|
||||||
this.ErrorPage(err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
idleTimeoutJSON, err := (&shared.TimeDuration{
|
var ossJSON []byte = nil
|
||||||
Count: int64(params.IdleTimeout),
|
var connTimeoutJSON []byte
|
||||||
Unit: shared.TimeDurationUnitSecond,
|
var readTimeoutJSON []byte
|
||||||
}).AsJSON()
|
var idleTimeoutJSON []byte
|
||||||
if err != nil {
|
var certRefJSON []byte
|
||||||
this.ErrorPage(err)
|
var pbAddr = &pb.NetworkAddress{
|
||||||
return
|
Protocol: params.Protocol,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 证书
|
if ossConfig != nil { // OSS
|
||||||
var certIds = []int64{}
|
ossJSON, err = json.Marshal(ossConfig)
|
||||||
if len(params.CertIdsJSON) > 0 {
|
|
||||||
err = json.Unmarshal(params.CertIdsJSON, &certIds)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
err = ossConfig.Init()
|
||||||
var certRefJSON []byte
|
if err != nil {
|
||||||
if len(certIds) > 0 {
|
this.Fail("校验OSS配置时出错:" + err.Error())
|
||||||
var certId = certIds[0]
|
return
|
||||||
if certId > 0 {
|
}
|
||||||
var certRef = &sslconfigs.SSLCertRef{
|
} else { // 普通源站
|
||||||
IsOn: true,
|
params.Must.
|
||||||
CertId: certId,
|
Field("addr", params.Addr).
|
||||||
|
Require("请输入源站地址")
|
||||||
|
|
||||||
|
var addr = params.Addr
|
||||||
|
|
||||||
|
// 是否是完整的地址
|
||||||
|
if (params.Protocol == "http" || params.Protocol == "https") && regexp.MustCompile(`^(http|https)://`).MatchString(addr) {
|
||||||
|
u, err := url.Parse(addr)
|
||||||
|
if err == nil {
|
||||||
|
addr = u.Host
|
||||||
}
|
}
|
||||||
certRefJSON, err = json.Marshal(certRef)
|
}
|
||||||
|
|
||||||
|
addr = strings.ReplaceAll(addr, ":", ":")
|
||||||
|
addr = regexp.MustCompile(`\s+`).ReplaceAllString(addr, "")
|
||||||
|
portIndex := strings.LastIndex(addr, ":")
|
||||||
|
if portIndex < 0 {
|
||||||
|
if params.Protocol == "http" {
|
||||||
|
addr += ":80"
|
||||||
|
} else if params.Protocol == "https" {
|
||||||
|
addr += ":443"
|
||||||
|
} else {
|
||||||
|
this.FailField("addr", "源站地址中需要带有端口")
|
||||||
|
}
|
||||||
|
portIndex = strings.LastIndex(addr, ":")
|
||||||
|
}
|
||||||
|
var host = addr[:portIndex]
|
||||||
|
var port = addr[portIndex+1:]
|
||||||
|
// 检查端口号
|
||||||
|
if port == "0" {
|
||||||
|
this.FailField("addr", "源站端口号不能为0")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !configutils.HasVariables(port) {
|
||||||
|
// 必须是整数
|
||||||
|
if !regexp.MustCompile(`^\d+$`).MatchString(port) {
|
||||||
|
this.FailField("addr", "源站端口号只能为整数")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var portInt = types.Int(port)
|
||||||
|
if portInt == 0 {
|
||||||
|
this.FailField("addr", "源站端口号不能为0")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if portInt > 65535 {
|
||||||
|
this.FailField("addr", "源站端口号不能大于65535")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pbAddr = &pb.NetworkAddress{
|
||||||
|
Protocol: params.Protocol,
|
||||||
|
Host: host,
|
||||||
|
PortRange: port,
|
||||||
|
}
|
||||||
|
|
||||||
|
connTimeoutJSON, err = (&shared.TimeDuration{
|
||||||
|
Count: int64(params.ConnTimeout),
|
||||||
|
Unit: shared.TimeDurationUnitSecond,
|
||||||
|
}).AsJSON()
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
readTimeoutJSON, err = (&shared.TimeDuration{
|
||||||
|
Count: int64(params.ReadTimeout),
|
||||||
|
Unit: shared.TimeDurationUnitSecond,
|
||||||
|
}).AsJSON()
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
idleTimeoutJSON, err = (&shared.TimeDuration{
|
||||||
|
Count: int64(params.IdleTimeout),
|
||||||
|
Unit: shared.TimeDurationUnitSecond,
|
||||||
|
}).AsJSON()
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 证书
|
||||||
|
var certIds = []int64{}
|
||||||
|
if len(params.CertIdsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(params.CertIdsJSON, &certIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(certIds) > 0 {
|
||||||
|
var certId = certIds[0]
|
||||||
|
if certId > 0 {
|
||||||
|
var certRef = &sslconfigs.SSLCertRef{
|
||||||
|
IsOn: true,
|
||||||
|
CertId: certId,
|
||||||
|
}
|
||||||
|
certRefJSON, err = json.Marshal(certRef)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 专属域名
|
// 专属域名
|
||||||
@@ -258,13 +307,10 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, err = this.RPC().OriginRPC().UpdateOrigin(this.AdminContext(), &pb.UpdateOriginRequest{
|
_, err = this.RPC().OriginRPC().UpdateOrigin(this.AdminContext(), &pb.UpdateOriginRequest{
|
||||||
OriginId: params.OriginId,
|
OriginId: params.OriginId,
|
||||||
Name: params.Name,
|
Name: params.Name,
|
||||||
Addr: &pb.NetworkAddress{
|
Addr: pbAddr,
|
||||||
Protocol: params.Protocol,
|
OssJSON: ossJSON,
|
||||||
Host: host,
|
|
||||||
PortRange: port,
|
|
||||||
},
|
|
||||||
Description: params.Description,
|
Description: params.Description,
|
||||||
Weight: params.Weight,
|
Weight: params.Weight,
|
||||||
IsOn: params.IsOn,
|
IsOn: params.IsOn,
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package origins
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ossconfigs"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this *UpdatePopupAction) getOSSHook() {
|
||||||
|
this.Data["ossTypes"] = []maps.Map{}
|
||||||
|
this.Data["ossBucketParams"] = []maps.Map{}
|
||||||
|
this.Data["ossForm"] = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UpdatePopupAction) postOSSHook(protocol string) (config *ossconfigs.OSSConfig, goNext bool, err error) {
|
||||||
|
goNext = true
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
AllowEmpty: true,
|
AllowEmpty: true,
|
||||||
AllowSameDomain: true,
|
AllowSameDomain: true,
|
||||||
AllowDomains: nil,
|
AllowDomains: nil,
|
||||||
|
CheckOrigin: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
var m = maps.Map{
|
var m = maps.Map{
|
||||||
"id": originConfig.Id,
|
"id": originConfig.Id,
|
||||||
"weight": originConfig.Weight,
|
"weight": originConfig.Weight,
|
||||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
"addr": originConfig.AddrSummary(),
|
||||||
|
"isOSS": originConfig.IsOSS(),
|
||||||
"name": originConfig.Name,
|
"name": originConfig.Name,
|
||||||
"isOn": originConfig.IsOn,
|
"isOn": originConfig.IsOn,
|
||||||
"domains": originConfig.Domains,
|
"domains": originConfig.Domains,
|
||||||
@@ -104,7 +105,8 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
var m = maps.Map{
|
var m = maps.Map{
|
||||||
"id": originConfig.Id,
|
"id": originConfig.Id,
|
||||||
"weight": originConfig.Weight,
|
"weight": originConfig.Weight,
|
||||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
"addr": originConfig.AddrSummary(),
|
||||||
|
"isOSS": originConfig.IsOSS(),
|
||||||
"name": originConfig.Name,
|
"name": originConfig.Name,
|
||||||
"isOn": originConfig.IsOn,
|
"isOn": originConfig.IsOn,
|
||||||
"domains": originConfig.Domains,
|
"domains": originConfig.Domains,
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
_, err := this.RPC().SSLPolicyRPC().UpdateSSLPolicy(this.AdminContext(), &pb.UpdateSSLPolicyRequest{
|
_, err := this.RPC().SSLPolicyRPC().UpdateSSLPolicy(this.AdminContext(), &pb.UpdateSSLPolicyRequest{
|
||||||
SslPolicyId: sslPolicyId,
|
SslPolicyId: sslPolicyId,
|
||||||
Http2Enabled: sslPolicy.HTTP2Enabled,
|
Http2Enabled: sslPolicy.HTTP2Enabled,
|
||||||
|
Http3Enabled: sslPolicy.HTTP3Enabled,
|
||||||
MinVersion: sslPolicy.MinVersion,
|
MinVersion: sslPolicy.MinVersion,
|
||||||
SslCertsJSON: certsJSON,
|
SslCertsJSON: certsJSON,
|
||||||
HstsJSON: hstsJSON,
|
HstsJSON: hstsJSON,
|
||||||
@@ -144,6 +145,7 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
} else {
|
} else {
|
||||||
resp, err := this.RPC().SSLPolicyRPC().CreateSSLPolicy(this.AdminContext(), &pb.CreateSSLPolicyRequest{
|
resp, err := this.RPC().SSLPolicyRPC().CreateSSLPolicy(this.AdminContext(), &pb.CreateSSLPolicyRequest{
|
||||||
Http2Enabled: sslPolicy.HTTP2Enabled,
|
Http2Enabled: sslPolicy.HTTP2Enabled,
|
||||||
|
Http3Enabled: sslPolicy.HTTP3Enabled,
|
||||||
MinVersion: sslPolicy.MinVersion,
|
MinVersion: sslPolicy.MinVersion,
|
||||||
SslCertsJSON: certsJSON,
|
SslCertsJSON: certsJSON,
|
||||||
HstsJSON: hstsJSON,
|
HstsJSON: hstsJSON,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
"github.com/iwind/TeaGo/actions"
|
"github.com/iwind/TeaGo/actions"
|
||||||
"github.com/iwind/TeaGo/lists"
|
"github.com/iwind/TeaGo/lists"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
@@ -41,7 +42,7 @@ func (this *CountriesAction) RunGet(params struct {
|
|||||||
this.NotFound("firewallPolicy", params.FirewallPolicyId)
|
this.NotFound("firewallPolicy", params.FirewallPolicyId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
selectedCountryIds := []int64{}
|
var selectedCountryIds = []int64{}
|
||||||
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
|
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
|
||||||
selectedCountryIds = policyConfig.Inbound.Region.DenyCountryIds
|
selectedCountryIds = policyConfig.Inbound.Region.DenyCountryIds
|
||||||
}
|
}
|
||||||
@@ -51,7 +52,7 @@ func (this *CountriesAction) RunGet(params struct {
|
|||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
countryMaps := []maps.Map{}
|
var countryMaps = []maps.Map{}
|
||||||
for _, country := range countriesResp.RegionCountries {
|
for _, country := range countriesResp.RegionCountries {
|
||||||
countryMaps = append(countryMaps, maps.Map{
|
countryMaps = append(countryMaps, maps.Map{
|
||||||
"id": country.Id,
|
"id": country.Id,
|
||||||
@@ -62,6 +63,18 @@ func (this *CountriesAction) RunGet(params struct {
|
|||||||
}
|
}
|
||||||
this.Data["countries"] = countryMaps
|
this.Data["countries"] = countryMaps
|
||||||
|
|
||||||
|
// except & only URL Patterns
|
||||||
|
this.Data["exceptURLPatterns"] = []*shared.URLPattern{}
|
||||||
|
this.Data["onlyURLPatterns"] = []*shared.URLPattern{}
|
||||||
|
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
|
||||||
|
if len(policyConfig.Inbound.Region.CountryExceptURLPatterns) > 0 {
|
||||||
|
this.Data["exceptURLPatterns"] = policyConfig.Inbound.Region.CountryExceptURLPatterns
|
||||||
|
}
|
||||||
|
if len(policyConfig.Inbound.Region.CountryOnlyURLPatterns) > 0 {
|
||||||
|
this.Data["onlyURLPatterns"] = policyConfig.Inbound.Region.CountryOnlyURLPatterns
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WAF是否启用
|
// WAF是否启用
|
||||||
webConfig, err := dao.SharedHTTPWebDAO.FindWebConfigWithServerId(this.AdminContext(), params.ServerId)
|
webConfig, err := dao.SharedHTTPWebDAO.FindWebConfigWithServerId(this.AdminContext(), params.ServerId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -77,6 +90,9 @@ func (this *CountriesAction) RunPost(params struct {
|
|||||||
FirewallPolicyId int64
|
FirewallPolicyId int64
|
||||||
CountryIds []int64
|
CountryIds []int64
|
||||||
|
|
||||||
|
ExceptURLPatternsJSON []byte
|
||||||
|
OnlyURLPatternsJSON []byte
|
||||||
|
|
||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
}) {
|
}) {
|
||||||
// 日志
|
// 日志
|
||||||
@@ -102,6 +118,34 @@ func (this *CountriesAction) RunPost(params struct {
|
|||||||
}
|
}
|
||||||
policyConfig.Inbound.Region.DenyCountryIds = params.CountryIds
|
policyConfig.Inbound.Region.DenyCountryIds = params.CountryIds
|
||||||
|
|
||||||
|
// 例外URL
|
||||||
|
var exceptURLPatterns = []*shared.URLPattern{}
|
||||||
|
if len(params.ExceptURLPatternsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(params.ExceptURLPatternsJSON, &exceptURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
this.Fail("校验例外URL参数失败:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
policyConfig.Inbound.Region.CountryExceptURLPatterns = exceptURLPatterns
|
||||||
|
|
||||||
|
// 限制URL
|
||||||
|
var onlyURLPatterns = []*shared.URLPattern{}
|
||||||
|
if len(params.OnlyURLPatternsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(params.OnlyURLPatternsJSON, &onlyURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
this.Fail("校验限制URL参数失败:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
policyConfig.Inbound.Region.CountryOnlyURLPatterns = onlyURLPatterns
|
||||||
|
|
||||||
|
err = policyConfig.Init()
|
||||||
|
if err != nil {
|
||||||
|
this.Fail("配置校验失败:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
inboundJSON, err := json.Marshal(policyConfig.Inbound)
|
inboundJSON, err := json.Marshal(policyConfig.Inbound)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
"github.com/iwind/TeaGo/actions"
|
"github.com/iwind/TeaGo/actions"
|
||||||
"github.com/iwind/TeaGo/lists"
|
"github.com/iwind/TeaGo/lists"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
@@ -41,7 +42,7 @@ func (this *ProvincesAction) RunGet(params struct {
|
|||||||
this.NotFound("firewallPolicy", params.FirewallPolicyId)
|
this.NotFound("firewallPolicy", params.FirewallPolicyId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
selectedProvinceIds := []int64{}
|
var selectedProvinceIds = []int64{}
|
||||||
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
|
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
|
||||||
selectedProvinceIds = policyConfig.Inbound.Region.DenyProvinceIds
|
selectedProvinceIds = policyConfig.Inbound.Region.DenyProvinceIds
|
||||||
}
|
}
|
||||||
@@ -53,7 +54,7 @@ func (this *ProvincesAction) RunGet(params struct {
|
|||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
provinceMaps := []maps.Map{}
|
var provinceMaps = []maps.Map{}
|
||||||
for _, province := range provincesResp.RegionProvinces {
|
for _, province := range provincesResp.RegionProvinces {
|
||||||
provinceMaps = append(provinceMaps, maps.Map{
|
provinceMaps = append(provinceMaps, maps.Map{
|
||||||
"id": province.Id,
|
"id": province.Id,
|
||||||
@@ -63,6 +64,18 @@ func (this *ProvincesAction) RunGet(params struct {
|
|||||||
}
|
}
|
||||||
this.Data["provinces"] = provinceMaps
|
this.Data["provinces"] = provinceMaps
|
||||||
|
|
||||||
|
// except & only URL Patterns
|
||||||
|
this.Data["exceptURLPatterns"] = []*shared.URLPattern{}
|
||||||
|
this.Data["onlyURLPatterns"] = []*shared.URLPattern{}
|
||||||
|
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
|
||||||
|
if len(policyConfig.Inbound.Region.ProvinceExceptURLPatterns) > 0 {
|
||||||
|
this.Data["exceptURLPatterns"] = policyConfig.Inbound.Region.ProvinceExceptURLPatterns
|
||||||
|
}
|
||||||
|
if len(policyConfig.Inbound.Region.ProvinceOnlyURLPatterns) > 0 {
|
||||||
|
this.Data["onlyURLPatterns"] = policyConfig.Inbound.Region.ProvinceOnlyURLPatterns
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WAF是否启用
|
// WAF是否启用
|
||||||
webConfig, err := dao.SharedHTTPWebDAO.FindWebConfigWithServerId(this.AdminContext(), params.ServerId)
|
webConfig, err := dao.SharedHTTPWebDAO.FindWebConfigWithServerId(this.AdminContext(), params.ServerId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -78,6 +91,9 @@ func (this *ProvincesAction) RunPost(params struct {
|
|||||||
FirewallPolicyId int64
|
FirewallPolicyId int64
|
||||||
ProvinceIds []int64
|
ProvinceIds []int64
|
||||||
|
|
||||||
|
ExceptURLPatternsJSON []byte
|
||||||
|
OnlyURLPatternsJSON []byte
|
||||||
|
|
||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
}) {
|
}) {
|
||||||
// 日志
|
// 日志
|
||||||
@@ -103,6 +119,34 @@ func (this *ProvincesAction) RunPost(params struct {
|
|||||||
}
|
}
|
||||||
policyConfig.Inbound.Region.DenyProvinceIds = params.ProvinceIds
|
policyConfig.Inbound.Region.DenyProvinceIds = params.ProvinceIds
|
||||||
|
|
||||||
|
// 例外URL
|
||||||
|
var exceptURLPatterns = []*shared.URLPattern{}
|
||||||
|
if len(params.ExceptURLPatternsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(params.ExceptURLPatternsJSON, &exceptURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
this.Fail("校验例外URL参数失败:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
policyConfig.Inbound.Region.ProvinceExceptURLPatterns = exceptURLPatterns
|
||||||
|
|
||||||
|
// 限制URL
|
||||||
|
var onlyURLPatterns = []*shared.URLPattern{}
|
||||||
|
if len(params.OnlyURLPatternsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(params.OnlyURLPatternsJSON, &onlyURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
this.Fail("校验限制URL参数失败:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
policyConfig.Inbound.Region.ProvinceOnlyURLPatterns = onlyURLPatterns
|
||||||
|
|
||||||
|
err = policyConfig.Init()
|
||||||
|
if err != nil {
|
||||||
|
this.Fail("配置校验失败:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
inboundJSON, err := json.Marshal(policyConfig.Inbound)
|
inboundJSON, err := json.Marshal(policyConfig.Inbound)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
|
|||||||
@@ -106,8 +106,13 @@ func (this *ServerHelper) createLeftMenu(action *actions.ActionObject) {
|
|||||||
|
|
||||||
// TABBAR
|
// TABBAR
|
||||||
selectedTabbar, _ := action.Data["mainTab"]
|
selectedTabbar, _ := action.Data["mainTab"]
|
||||||
tabbar := actionutils.NewTabbar()
|
var tabbar = actionutils.NewTabbar()
|
||||||
tabbar.Add("服务列表", "", "/servers", "", false)
|
tabbar.Add("", "", "/servers", "left arrow", false)
|
||||||
|
if len(serverConfig.Name) > 0 {
|
||||||
|
var item = tabbar.Add(serverConfig.Name, "", "/servers/server?serverId="+serverIdString, "angle right", true)
|
||||||
|
item.IsTitle = true
|
||||||
|
}
|
||||||
|
|
||||||
if teaconst.IsPlus {
|
if teaconst.IsPlus {
|
||||||
tabbar.Add("看板", "", "/servers/server/boards?serverId="+serverIdString, "dashboard", selectedTabbar == "board")
|
tabbar.Add("看板", "", "/servers/server/boards?serverId="+serverIdString, "dashboard", selectedTabbar == "board")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/api/node"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/api/node"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/settingutils"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/settingutils"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||||
"github.com/iwind/TeaGo"
|
"github.com/iwind/TeaGo"
|
||||||
@@ -14,7 +14,7 @@ func init() {
|
|||||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeSetting)).
|
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeSetting)).
|
||||||
Helper(NewHelper()).
|
Helper(NewHelper()).
|
||||||
Helper(settingutils.NewAdvancedHelper("apiNodes")).
|
Helper(settingutils.NewAdvancedHelper("apiNodes")).
|
||||||
Prefix("/api").
|
Prefix("/settings/api").
|
||||||
Get("", new(IndexAction)).
|
Get("", new(IndexAction)).
|
||||||
Get("/methodStats", new(MethodStatsAction)).
|
Get("/methodStats", new(MethodStatsAction)).
|
||||||
GetPost("/node/createPopup", new(node.CreatePopupAction)).
|
GetPost("/node/createPopup", new(node.CreatePopupAction)).
|
||||||
@@ -12,7 +12,7 @@ func init() {
|
|||||||
server.
|
server.
|
||||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeSetting)).
|
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeSetting)).
|
||||||
Helper(settingutils.NewAdvancedHelper("apiNodes")).
|
Helper(settingutils.NewAdvancedHelper("apiNodes")).
|
||||||
Prefix("/api/node").
|
Prefix("/settings/api/node").
|
||||||
|
|
||||||
// 这里不受Helper的约束
|
// 这里不受Helper的约束
|
||||||
GetPost("/createAddrPopup", new(CreateAddrPopupAction)).
|
GetPost("/createAddrPopup", new(CreateAddrPopupAction)).
|
||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"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"
|
||||||
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CleanAction struct {
|
type CleanAction struct {
|
||||||
@@ -16,11 +17,20 @@ func (this *CleanAction) Init() {
|
|||||||
this.Nav("", "", "clean")
|
this.Nav("", "", "clean")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CleanAction) RunGet(params struct{}) {
|
func (this *CleanAction) RunGet(params struct {
|
||||||
|
OrderTable string
|
||||||
|
OrderSize string
|
||||||
|
}) {
|
||||||
|
this.Data["orderTable"] = params.OrderTable
|
||||||
|
this.Data["orderSize"] = params.OrderSize
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CleanAction) RunPost(params struct {
|
func (this *CleanAction) RunPost(params struct {
|
||||||
|
OrderTable string
|
||||||
|
OrderSize string
|
||||||
|
|
||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
}) {
|
}) {
|
||||||
tablesResp, err := this.RPC().DBRPC().FindAllDBTables(this.AdminContext(), &pb.FindAllDBTablesRequest{})
|
tablesResp, err := this.RPC().DBRPC().FindAllDBTables(this.AdminContext(), &pb.FindAllDBTablesRequest{})
|
||||||
@@ -28,9 +38,33 @@ func (this *CleanAction) RunPost(params struct {
|
|||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var tables = tablesResp.DbTables
|
||||||
|
|
||||||
tableMaps := []maps.Map{}
|
// 排序
|
||||||
for _, table := range tablesResp.DbTables {
|
switch params.OrderTable {
|
||||||
|
case "asc":
|
||||||
|
sort.Slice(tables, func(i, j int) bool {
|
||||||
|
return tables[i].Name < tables[j].Name
|
||||||
|
})
|
||||||
|
case "desc":
|
||||||
|
sort.Slice(tables, func(i, j int) bool {
|
||||||
|
return tables[i].Name > tables[j].Name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
switch params.OrderSize {
|
||||||
|
case "asc":
|
||||||
|
sort.Slice(tables, func(i, j int) bool {
|
||||||
|
return tables[i].DataLength+tables[i].IndexLength < tables[j].DataLength+tables[j].IndexLength
|
||||||
|
})
|
||||||
|
case "desc":
|
||||||
|
sort.Slice(tables, func(i, j int) bool {
|
||||||
|
return tables[i].DataLength+tables[i].IndexLength > tables[j].DataLength+tables[j].IndexLength
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var tableMaps = []maps.Map{}
|
||||||
|
for _, table := range tables {
|
||||||
if !table.IsBaseTable || (!table.CanClean && !table.CanDelete) {
|
if !table.IsBaseTable || (!table.CanClean && !table.CanDelete) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user