This commit is contained in:
unknown
2026-02-04 20:27:13 +08:00
commit 3b042d1dad
9410 changed files with 1488147 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
package basic
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "setting", "index")
this.SecondMenu("basic")
}
func (this *IndexAction) RunGet(params struct {
ServerId int64
}) {
resp, err := this.RPC().ServerRPC().FindEnabledUserServerBasic(this.UserContext(), &pb.FindEnabledUserServerBasicRequest{ServerId: params.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
server := resp.Server
if server == nil {
this.NotFound("server", params.ServerId)
return
}
this.Data["name"] = server.Name
this.Show()
}
func (this *IndexAction) RunPost(params struct {
ServerId int64
Name string
Must *actions.Must
CSRF *actionutils.CSRF
}) {
params.Must.
Field("name", params.Name).
Require("请输入服务名称")
_, err := this.RPC().ServerRPC().UpdateEnabledUserServerBasic(this.UserContext(), &pb.UpdateEnabledUserServerBasicRequest{
ServerId: params.ServerId,
Name: params.Name,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,18 @@
package basic
import (
"github.com/TeaOSLab/EdgeUser/internal/web/actions/default/lb/serverutils"
"github.com/TeaOSLab/EdgeUser/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth("")).
Helper(serverutils.NewServerHelper()).
Prefix("/lb/server/settings/basic").
GetPost("", new(IndexAction)).
EndAll()
})
}

View File

@@ -0,0 +1,33 @@
package dns
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "setting", "index")
this.SecondMenu("dns")
}
func (this *IndexAction) RunGet(params struct {
ServerId int64
}) {
dnsInfoResp, err := this.RPC().ServerRPC().FindEnabledServerDNS(this.UserContext(), &pb.FindEnabledServerDNSRequest{ServerId: params.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
this.Data["dnsName"] = dnsInfoResp.DnsName
if dnsInfoResp.Domain != nil {
this.Data["dnsDomain"] = dnsInfoResp.Domain.Name
} else {
this.Data["dnsDomain"] = ""
}
this.Show()
}

View File

@@ -0,0 +1,18 @@
package dns
import (
"github.com/TeaOSLab/EdgeUser/internal/web/actions/default/lb/serverutils"
"github.com/TeaOSLab/EdgeUser/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth("")).
Helper(serverutils.NewServerHelper()).
Prefix("/lb/server/settings/dns").
GetPost("", new(IndexAction)).
EndAll()
})
}

View File

@@ -0,0 +1,73 @@
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package plan
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
)
// DataAction 套餐相关数据
type DataAction struct {
actionutils.ParentAction
}
func (this *DataAction) RunPost(params struct {
ServerId int64
UserPlanId int64
}) {
userPlanResp, err := this.RPC().UserPlanRPC().FindEnabledUserPlan(this.UserContext(), &pb.FindEnabledUserPlanRequest{UserPlanId: params.UserPlanId})
if err != nil {
this.ErrorPage(err)
return
}
var userPlan = userPlanResp.UserPlan
if userPlan == nil || userPlan.Plan == nil {
this.NotFound("userPlan", params.UserPlanId)
return
}
var plan = userPlan.Plan
// 网站数
countServersResp, err := this.RPC().ServerRPC().CountAllUserServers(this.UserContext(), &pb.CountAllUserServersRequest{
UserPlanId: params.UserPlanId,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Data["servers"] = maps.Map{
"current": countServersResp.Count,
"max": plan.TotalServers,
"isValid": plan.TotalServers <= 0 || countServersResp.Count+1 <= int64(plan.TotalServers),
}
// 当前网站域名数
countServerNamesResp, err := this.RPC().ServerRPC().CountServerNames(this.UserContext(), &pb.CountServerNamesRequest{ServerId: params.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
this.Data["serverNames"] = maps.Map{
"current": countServerNamesResp.Count,
"max": plan.TotalServerNamesPerServer,
"isValid": plan.TotalServerNamesPerServer <= 0 || countServerNamesResp.Count <= int64(plan.TotalServerNamesPerServer),
}
// 总域名数
countAllServerNamesResp, err := this.RPC().ServerRPC().CountAllServerNamesWithUserId(this.UserContext(), &pb.CountAllServerNamesWithUserIdRequest{
UserPlanId: params.UserPlanId,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Data["allServerNames"] = maps.Map{
"current": countAllServerNamesResp.Count,
"max": plan.TotalServerNames,
"isValid": plan.TotalServerNames <= 0 || countAllServerNamesResp.Count+countServerNamesResp.Count <= int64(plan.TotalServerNames),
}
this.Success()
}

View File

@@ -0,0 +1,244 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package plan
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
"github.com/TeaOSLab/EdgeUser/internal/utils/numberutils"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "setting", "index")
this.SecondMenu("plan")
}
func (this *IndexAction) RunGet(params struct {
ServerId int64
}) {
if !this.ValidateFeature(userconfigs.UserFeatureCodePlan, params.ServerId) {
return
}
// 所有可选套餐
userPlansResp, err := this.RPC().UserPlanRPC().FindAllEnabledUserPlansForServer(this.UserContext(), &pb.FindAllEnabledUserPlansForServerRequest{
UserId: this.UserId(),
ServerId: params.ServerId,
})
if err != nil {
this.ErrorPage(err)
return
}
var userPlanMaps = []maps.Map{}
for _, userPlan := range userPlansResp.UserPlans {
if userPlan.Plan == nil {
continue
}
var name = userPlan.Plan.Name
if len(userPlan.Name) > 0 {
name += "-" + userPlan.Name
}
userPlanMaps = append(userPlanMaps, maps.Map{
"id": userPlan.Id,
"name": name,
"dayTo": userPlan.DayTo,
"totalServers": userPlan.Plan.TotalServers,
"totalServerNames": userPlan.Plan.TotalServerNames,
"totalServerNamesPerServer": userPlan.Plan.TotalServerNamesPerServer,
})
}
this.Data["userPlans"] = userPlanMaps
// 当前使用的套餐
userPlanResp, err := this.RPC().ServerRPC().FindServerUserPlan(this.UserContext(), &pb.FindServerUserPlanRequest{ServerId: params.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
// 用户套餐信息
var userPlanMap = maps.Map{"id": 0}
var userPlan = userPlanResp.UserPlan
this.Data["hasTrafficLimit"] = false
if userPlan != nil {
userPlanMap = maps.Map{
"id": userPlan.Id,
"dayTo": userPlan.DayTo,
"isExpired": timeutil.Format("Y-m-d") > userPlan.DayTo,
"name": userPlan.Name,
"plan": nil,
}
var plan = userPlan.Plan
if plan != nil {
// 流量限制
var trafficLimit = &serverconfigs.TrafficLimitConfig{}
if len(plan.TrafficLimitJSON) > 0 {
err = json.Unmarshal(plan.TrafficLimitJSON, trafficLimit)
if err != nil {
this.ErrorPage(err)
return
}
}
userPlanMap["plan"] = maps.Map{
"id": plan.Id,
"name": plan.Name,
"trafficLimit": trafficLimit,
}
if !trafficLimit.IsEmpty() {
this.Data["hasTrafficLimit"] = true
}
}
}
this.Data["userPlan"] = userPlanMap
// 当前网站流量
{
trafficStatResp, err := this.RPC().ServerDailyRPC().SumServerDailyStats(this.UserContext(), &pb.SumServerDailyStatsRequest{
ServerId: params.ServerId,
Day: timeutil.Format("Ymd"),
})
if err != nil {
this.ErrorPage(err)
return
}
var trafficDailyBytes int64 = 0
if trafficStatResp.ServerDailyStat != nil {
trafficDailyBytes = trafficStatResp.ServerDailyStat.Bytes
}
this.Data["trafficDailyFormat"] = numberutils.FormatBytes(trafficDailyBytes)
}
{
trafficStatResp, err := this.RPC().ServerDailyRPC().SumServerMonthlyStats(this.UserContext(), &pb.SumServerMonthlyStatsRequest{
ServerId: params.ServerId,
Month: timeutil.Format("Ym"),
})
if err != nil {
this.ErrorPage(err)
return
}
var trafficMonthlyBytes int64 = 0
if trafficStatResp.ServerMonthlyStat != nil {
trafficMonthlyBytes = trafficStatResp.ServerMonthlyStat.Bytes
}
this.Data["trafficMonthlyFormat"] = numberutils.FormatBytes(trafficMonthlyBytes)
}
this.Show()
}
func (this *IndexAction) RunPost(params struct {
ServerId int64
IsChanged bool
UserPlanId int64
Must *actions.Must
CSRF *actionutils.CSRF
}) {
if !params.IsChanged {
this.Success()
return
}
if params.UserPlanId <= 0 { // 取消绑定
defer this.CreateLogInfo(codes.UserPlan_LogCancelUserPlanFromServer, params.ServerId)
} else { // 变更绑定
defer this.CreateLogInfo(codes.UserPlan_LogBindUserPlanToServer, params.ServerId, params.UserPlanId)
}
// 前后套餐是否一致
oldUserPlanResp, err := this.RPC().ServerRPC().FindServerUserPlan(this.UserContext(), &pb.FindServerUserPlanRequest{ServerId: params.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
if oldUserPlanResp.UserPlan != nil && oldUserPlanResp.UserPlan.Id == params.UserPlanId {
this.Success()
return
}
// 检查套餐
if params.UserPlanId > 0 {
userPlanResp, err := this.RPC().UserPlanRPC().FindEnabledUserPlan(this.UserContext(), &pb.FindEnabledUserPlanRequest{UserPlanId: params.UserPlanId})
if err != nil {
this.ErrorPage(err)
return
}
var userPlan = userPlanResp.UserPlan
if userPlan == nil || userPlan.Plan == nil {
this.NotFound("userPlan", params.UserPlanId)
return
}
var plan = userPlan.Plan
// server
if plan.TotalServers > 0 {
countServersResp, err := this.RPC().ServerRPC().CountAllUserServers(this.UserContext(), &pb.CountAllUserServersRequest{
UserPlanId: params.UserPlanId,
})
if err != nil {
this.ErrorPage(err)
return
}
if countServersResp.Count+1 > int64(plan.TotalServers) {
this.Fail("已绑定网站数超出当前套餐限制")
return
}
}
countServerNamesResp, err := this.RPC().ServerRPC().CountServerNames(this.UserContext(), &pb.CountServerNamesRequest{ServerId: params.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
if plan.TotalServerNamesPerServer > 0 {
if countServerNamesResp.Count > int64(plan.TotalServerNamesPerServer) {
this.Fail("当前网站域名数超出当前套餐限制")
return
}
}
if plan.TotalServerNames > 0 {
countAllServerNamesResp, err := this.RPC().ServerRPC().CountAllServerNamesWithUserId(this.UserContext(), &pb.CountAllServerNamesWithUserIdRequest{
UserPlanId: params.UserPlanId,
})
if err != nil {
this.ErrorPage(err)
return
}
if countAllServerNamesResp.Count+countServerNamesResp.Count > int64(plan.TotalServerNames) {
this.Fail("已绑定域名数超出当前套餐限制")
return
}
}
}
// 提交修改
_, err = this.RPC().ServerRPC().UpdateServerUserPlan(this.UserContext(), &pb.UpdateServerUserPlanRequest{
ServerId: params.ServerId,
UserPlanId: params.UserPlanId,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,19 @@
package plan
import (
"github.com/TeaOSLab/EdgeUser/internal/web/actions/default/lb/serverutils"
"github.com/TeaOSLab/EdgeUser/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth("")).
Helper(serverutils.NewServerHelper()).
Prefix("/lb/server/settings/plan").
GetPost("", new(IndexAction)).
Post("/data", new(DataAction)).
EndAll()
})
}

View File

@@ -0,0 +1,101 @@
package reverseProxy
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
)
// IndexAction 源站列表
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.FirstMenu("index")
}
func (this *IndexAction) RunGet(params struct {
ServerId int64
}) {
serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.UserContext(), &pb.FindEnabledServerTypeRequest{ServerId: params.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
var serverType = serverTypeResp.Type
reverseProxyResp, err := this.RPC().ServerRPC().FindAndInitServerReverseProxyConfig(this.UserContext(), &pb.FindAndInitServerReverseProxyConfigRequest{ServerId: params.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
var reverseProxyRef = &serverconfigs.ReverseProxyRef{}
err = json.Unmarshal(reverseProxyResp.ReverseProxyRefJSON, reverseProxyRef)
if err != nil {
this.ErrorPage(err)
return
}
this.Data["reverseProxyRef"] = reverseProxyRef
reverseProxy := &serverconfigs.ReverseProxyConfig{}
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
if err != nil {
this.ErrorPage(err)
return
}
this.Data["reverseProxyConfig"] = reverseProxy
this.Data["serverType"] = serverType
var primaryOriginMaps = []maps.Map{}
backupOriginMaps := []maps.Map{}
for _, originConfig := range reverseProxy.PrimaryOrigins {
var domains = originConfig.Domains
if len(domains) == 0 {
domains = []string{}
}
var m = maps.Map{
"id": originConfig.Id,
"weight": originConfig.Weight,
"addr": originConfig.AddrSummary(),
"isOSS": originConfig.IsOSS(),
"name": originConfig.Name,
"isOn": originConfig.IsOn,
"hasCert": originConfig.Cert != nil,
"host": originConfig.RequestHost,
"followPort": originConfig.FollowPort,
"http2Enabled": originConfig.HTTP2Enabled,
"domains": domains,
}
primaryOriginMaps = append(primaryOriginMaps, m)
}
for _, originConfig := range reverseProxy.BackupOrigins {
var domains = originConfig.Domains
if len(domains) == 0 {
domains = []string{}
}
var m = maps.Map{
"id": originConfig.Id,
"weight": originConfig.Weight,
"addr": originConfig.AddrSummary(),
"isOSS": originConfig.IsOSS(),
"name": originConfig.Name,
"isOn": originConfig.IsOn,
"hasCert": originConfig.Cert != nil,
"host": originConfig.RequestHost,
"followPort": originConfig.FollowPort,
"http2Enabled": originConfig.HTTP2Enabled,
"domains": domains,
}
backupOriginMaps = append(backupOriginMaps, m)
}
this.Data["primaryOrigins"] = primaryOriginMaps
this.Data["backupOrigins"] = backupOriginMaps
this.Show()
}

View File

@@ -0,0 +1,23 @@
package reverseProxy
import (
"github.com/TeaOSLab/EdgeUser/internal/web/actions/default/lb/serverutils"
"github.com/TeaOSLab/EdgeUser/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth("")).
Helper(serverutils.NewServerHelper()).
Data("mainTab", "setting").
Data("secondMenuItem", "reverseProxy").
Prefix("/lb/server/settings/reverseProxy").
Get("", new(IndexAction)).
GetPost("/scheduling", new(SchedulingAction)).
GetPost("/updateSchedulingPopup", new(UpdateSchedulingPopupAction)).
GetPost("/setting", new(SettingAction)).
EndAll()
})
}

View File

@@ -0,0 +1,45 @@
package reverseProxy
import (
"encoding/json"
"errors"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/schedulingconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
)
type SchedulingAction struct {
actionutils.ParentAction
}
func (this *SchedulingAction) Init() {
this.FirstMenu("scheduling")
}
func (this *SchedulingAction) RunGet(params struct {
ServerId int64
}) {
reverseProxyResp, err := this.RPC().ServerRPC().FindAndInitServerReverseProxyConfig(this.UserContext(), &pb.FindAndInitServerReverseProxyConfigRequest{ServerId: params.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
reverseProxy := &serverconfigs.ReverseProxyConfig{}
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
if err != nil {
this.ErrorPage(err)
return
}
this.Data["reverseProxyId"] = reverseProxy.Id
schedulingCode := reverseProxy.FindSchedulingConfig().Code
schedulingMap := schedulingconfigs.FindSchedulingType(schedulingCode)
if schedulingMap == nil {
this.ErrorPage(errors.New("invalid scheduling code '" + schedulingCode + "'"))
return
}
this.Data["scheduling"] = schedulingMap
this.Show()
}

View File

@@ -0,0 +1,107 @@
package reverseProxy
import (
"context"
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/types"
)
type SettingAction struct {
actionutils.ParentAction
}
func (this *SettingAction) Init() {
this.FirstMenu("setting")
}
func (this *SettingAction) RunGet(params struct {
ServerId int64
}) {
reverseProxyResp, err := this.RPC().ServerRPC().FindAndInitServerReverseProxyConfig(this.UserContext(), &pb.FindAndInitServerReverseProxyConfigRequest{ServerId: params.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
err = json.Unmarshal(reverseProxyResp.ReverseProxyRefJSON, reverseProxyRef)
if err != nil {
this.ErrorPage(err)
return
}
reverseProxy := &serverconfigs.ReverseProxyConfig{}
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
if err != nil {
this.ErrorPage(err)
return
}
this.Data["reverseProxyRef"] = reverseProxyRef
this.Data["reverseProxyConfig"] = reverseProxy
this.Show()
}
func (this *SettingAction) RunPost(params struct {
ServerId int64
ReverseProxyRefJSON []byte
ReverseProxyJSON []byte
Must *actions.Must
}) {
defer this.CreateLogInfo(codes.ServerReverseProxy_LogUpdateServerReverseProxySettings, params.ServerId)
var reverseProxyConfig = &serverconfigs.ReverseProxyConfig{}
err := json.Unmarshal(params.ReverseProxyJSON, reverseProxyConfig)
if err != nil {
this.ErrorPage(err)
return
}
err = reverseProxyConfig.Init(context.TODO())
if err != nil {
this.Fail("配置校验失败:" + err.Error())
}
// 设置是否启用
_, err = this.RPC().ServerRPC().UpdateServerReverseProxy(this.UserContext(), &pb.UpdateServerReverseProxyRequest{
ServerId: params.ServerId,
ReverseProxyJSON: params.ReverseProxyRefJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
// PROXY Protocol
var proxyProtocolJSON = []byte{}
if reverseProxyConfig.ProxyProtocol != nil {
proxyProtocolJSON, err = json.Marshal(reverseProxyConfig.ProxyProtocol)
if err != nil {
this.ErrorPage(err)
return
}
}
// 设置反向代理相关信息
_, err = this.RPC().ReverseProxyRPC().UpdateReverseProxy(this.UserContext(), &pb.UpdateReverseProxyRequest{
ReverseProxyId: reverseProxyConfig.Id,
RequestHostType: types.Int32(reverseProxyConfig.RequestHostType),
RequestHost: reverseProxyConfig.RequestHost,
RequestURI: reverseProxyConfig.RequestURI,
StripPrefix: reverseProxyConfig.StripPrefix,
AutoFlush: reverseProxyConfig.AutoFlush,
ProxyProtocolJSON: proxyProtocolJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,163 @@
package reverseProxy
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/schedulingconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
)
// 修改调度算法
type UpdateSchedulingPopupAction struct {
actionutils.ParentAction
}
func (this *UpdateSchedulingPopupAction) Init() {
}
func (this *UpdateSchedulingPopupAction) RunGet(params struct {
Type string
ServerId int64
ReverseProxyId int64
}) {
serverConfig, err := dao.SharedServerDAO.FindEnabledServerConfig(this.UserContext(), params.ServerId)
if err != nil {
this.ErrorPage(err)
return
}
if serverConfig == nil {
this.NotFound("server", params.ServerId)
return
}
this.Data["dataType"] = params.Type
this.Data["serverId"] = params.ServerId
this.Data["reverseProxyId"] = params.ReverseProxyId
reverseProxyResp, err := this.RPC().ReverseProxyRPC().FindEnabledReverseProxyConfig(this.UserContext(), &pb.FindEnabledReverseProxyConfigRequest{
ReverseProxyId: params.ReverseProxyId,
})
if err != nil {
this.ErrorPage(err)
return
}
configData := reverseProxyResp.ReverseProxyJSON
reverseProxyConfig := &serverconfigs.ReverseProxyConfig{}
err = json.Unmarshal(configData, reverseProxyConfig)
if err != nil {
this.ErrorPage(err)
return
}
schedulingObject := &serverconfigs.SchedulingConfig{
Code: "random",
Options: nil,
}
if reverseProxyConfig.Scheduling != nil {
schedulingObject = reverseProxyConfig.Scheduling
}
this.Data["scheduling"] = schedulingObject
// 调度类型
schedulingTypes := []maps.Map{}
for _, m := range schedulingconfigs.AllSchedulingTypes() {
networks, ok := m["networks"]
if !ok {
continue
}
if !types.IsSlice(networks) {
continue
}
if (serverConfig.IsHTTPFamily() && lists.Contains(networks, "http")) ||
(serverConfig.IsTCPFamily() && lists.Contains(networks, "tcp")) ||
(serverConfig.IsUDPFamily() && lists.Contains(networks, "udp")) {
schedulingTypes = append(schedulingTypes, m)
}
}
this.Data["schedulingTypes"] = schedulingTypes
this.Show()
}
func (this *UpdateSchedulingPopupAction) RunPost(params struct {
ServerId int64
ReverseProxyId int64
Type string
HashKey string
StickyType string
StickyParam string
Must *actions.Must
}) {
defer this.CreateLogInfo(codes.ReverseProxy_LogUpdateReverseProxyScheduling, params.ReverseProxyId)
reverseProxyResp, err := this.RPC().ReverseProxyRPC().FindEnabledReverseProxyConfig(this.UserContext(), &pb.FindEnabledReverseProxyConfigRequest{ReverseProxyId: params.ReverseProxyId})
if err != nil {
this.ErrorPage(err)
return
}
configData := reverseProxyResp.ReverseProxyJSON
reverseProxy := &serverconfigs.ReverseProxyConfig{}
err = json.Unmarshal(configData, reverseProxy)
if err != nil {
this.ErrorPage(err)
return
}
if reverseProxy.Scheduling == nil {
reverseProxy.FindSchedulingConfig()
}
options := maps.Map{}
if params.Type == "hash" {
params.Must.
Field("hashKey", params.HashKey).
Require("请输入Key")
options["key"] = params.HashKey
} else if params.Type == "sticky" {
params.Must.
Field("stickyType", params.StickyType).
Require("请选择参数类型").
Field("stickyParam", params.StickyParam).
Require("请输入参数名").
Match("^[a-zA-Z0-9]+$", "参数名只能是英文字母和数字的组合").
MaxCharacters(50, "参数名长度不能超过50位")
options["type"] = params.StickyType
options["param"] = params.StickyParam
}
if schedulingconfigs.FindSchedulingType(params.Type) == nil {
this.Fail("不支持此种算法")
}
reverseProxy.Scheduling.Code = params.Type
reverseProxy.Scheduling.Options = options
schedulingData, err := json.Marshal(reverseProxy.Scheduling)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().ReverseProxyRPC().UpdateReverseProxyScheduling(this.UserContext(), &pb.UpdateReverseProxySchedulingRequest{
ReverseProxyId: params.ReverseProxyId,
SchedulingJSON: schedulingData,
})
if err != nil {
this.ErrorPage(err)
}
this.Success()
}

View File

@@ -0,0 +1,143 @@
package tcp
import (
"encoding/json"
"fmt"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/types"
)
// IndexAction TCP设置
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "setting", "index")
this.SecondMenu("tcp")
}
func (this *IndexAction) RunGet(params struct {
ServerId int64
}) {
this.Data["canSpecifyPort"] = this.ValidateFeature(userconfigs.UserFeatureCodeServerTCPPort, params.ServerId)
server, err := dao.SharedServerDAO.FindEnabledServer(this.UserContext(), params.ServerId)
if err != nil {
this.ErrorPage(err)
return
}
if server == nil {
this.NotFound("server", params.ServerId)
return
}
tcpConfig := &serverconfigs.TCPProtocolConfig{}
if len(server.TcpJSON) > 0 {
err := json.Unmarshal(server.TcpJSON, tcpConfig)
if err != nil {
this.ErrorPage(err)
}
} else {
tcpConfig.IsOn = true
}
this.Data["serverType"] = server.Type
this.Data["tcpConfig"] = tcpConfig
this.Show()
}
func (this *IndexAction) RunPost(params struct {
ServerId int64
ServerType string
Addresses string
Must *actions.Must
}) {
defer this.CreateLogInfo(codes.ServerTCP_LogUpdateTCPSettings, params.ServerId)
canSpecifyPort := this.ValidateFeature(userconfigs.UserFeatureCodeServerTCPPort, params.ServerId)
server, err := dao.SharedServerDAO.FindEnabledServer(this.UserContext(), params.ServerId)
if err != nil {
this.ErrorPage(err)
return
}
if server == nil {
this.NotFound("server", params.ServerId)
return
}
addresses := []*serverconfigs.NetworkAddressConfig{}
err = json.Unmarshal([]byte(params.Addresses), &addresses)
if err != nil {
this.Fail("端口地址解析失败:" + err.Error())
}
// 检查端口是否被使用
clusterIdResp, err := this.RPC().UserRPC().FindUserNodeClusterId(this.UserContext(), &pb.FindUserNodeClusterIdRequest{UserId: this.UserId()})
if err != nil {
this.ErrorPage(err)
return
}
clusterId := clusterIdResp.NodeClusterId
if clusterId == 0 {
this.Fail("当前用户没有指定集群,不能使用此服务")
}
for _, address := range addresses {
port := types.Int32(address.PortRange)
if port < 1024 || port > 65534 {
this.Fail("'" + address.PortRange + "' 端口范围错误")
}
resp, err := this.RPC().NodeClusterRPC().CheckPortIsUsingInNodeCluster(this.UserContext(), &pb.CheckPortIsUsingInNodeClusterRequest{
Port: port,
NodeClusterId: clusterId,
ExcludeServerId: params.ServerId,
ExcludeProtocol: "tcp",
ProtocolFamily: "tcp",
})
if err != nil {
this.ErrorPage(err)
return
}
if resp.IsUsing {
this.Fail("端口 '" + fmt.Sprintf("%d", port) + "' 正在被别的服务或者同服务其他网络协议使用,请换一个")
}
}
tcpConfig := &serverconfigs.TCPProtocolConfig{}
if len(server.TcpJSON) > 0 {
err := json.Unmarshal(server.TcpJSON, tcpConfig)
if err != nil {
this.ErrorPage(err)
}
} else {
tcpConfig.IsOn = true
}
if canSpecifyPort {
tcpConfig.Listen = addresses
}
configData, err := json.Marshal(tcpConfig)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().ServerRPC().UpdateServerTCP(this.UserContext(), &pb.UpdateServerTCPRequest{
ServerId: params.ServerId,
TcpJSON: configData,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,18 @@
package tcp
import (
"github.com/TeaOSLab/EdgeUser/internal/web/actions/default/lb/serverutils"
"github.com/TeaOSLab/EdgeUser/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth("")).
Helper(serverutils.NewServerHelper()).
Prefix("/lb/server/settings/tcp").
GetPost("", new(IndexAction)).
EndAll()
})
}

View File

@@ -0,0 +1,246 @@
package tls
import (
"encoding/json"
"errors"
"fmt"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
)
// IndexAction TLS设置
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "setting", "index")
this.SecondMenu("tls")
}
func (this *IndexAction) RunGet(params struct {
ServerId int64
}) {
this.Data["canSpecifyPort"] = this.ValidateFeature(userconfigs.UserFeatureCodeServerTCPPort, params.ServerId)
server, err := dao.SharedServerDAO.FindEnabledServer(this.UserContext(), params.ServerId)
if err != nil {
this.ErrorPage(err)
return
}
if server == nil {
this.NotFound("server", params.ServerId)
return
}
tlsConfig := &serverconfigs.TLSProtocolConfig{}
if len(server.TlsJSON) > 0 {
err := json.Unmarshal(server.TlsJSON, tlsConfig)
if err != nil {
this.ErrorPage(err)
}
} else {
tlsConfig.IsOn = true
}
// SSL配置
var sslPolicy *sslconfigs.SSLPolicy
if tlsConfig.SSLPolicyRef != nil && tlsConfig.SSLPolicyRef.SSLPolicyId > 0 {
sslPolicyConfigResp, err := this.RPC().SSLPolicyRPC().FindEnabledSSLPolicyConfig(this.UserContext(), &pb.FindEnabledSSLPolicyConfigRequest{
SslPolicyId: tlsConfig.SSLPolicyRef.SSLPolicyId,
IgnoreData: true,
})
if err != nil {
this.ErrorPage(err)
return
}
sslPolicyConfigJSON := sslPolicyConfigResp.SslPolicyJSON
if len(sslPolicyConfigJSON) > 0 {
sslPolicy = &sslconfigs.SSLPolicy{}
err = json.Unmarshal(sslPolicyConfigJSON, sslPolicy)
if err != nil {
this.ErrorPage(err)
return
}
}
}
this.Data["serverType"] = server.Type
this.Data["tlsConfig"] = maps.Map{
"isOn": tlsConfig.IsOn,
"listen": tlsConfig.Listen,
"sslPolicy": sslPolicy,
}
this.Show()
}
func (this *IndexAction) RunPost(params struct {
ServerId int64
ServerType string
Addresses string
SslPolicyJSON []byte
Must *actions.Must
}) {
defer this.CreateLogInfo(codes.ServerTLS_LogUpdateTLSSettings, params.ServerId)
canSpecifyPort := this.ValidateFeature(userconfigs.UserFeatureCodeServerTCPPort, params.ServerId)
server, err := dao.SharedServerDAO.FindEnabledServer(this.UserContext(), params.ServerId)
if err != nil {
this.ErrorPage(err)
return
}
if server == nil {
this.NotFound("server", params.ServerId)
return
}
addresses := []*serverconfigs.NetworkAddressConfig{}
err = json.Unmarshal([]byte(params.Addresses), &addresses)
if err != nil {
this.Fail("端口地址解析失败:" + err.Error())
}
// 检查端口是否被使用
clusterIdResp, err := this.RPC().UserRPC().FindUserNodeClusterId(this.UserContext(), &pb.FindUserNodeClusterIdRequest{UserId: this.UserId()})
if err != nil {
this.ErrorPage(err)
return
}
clusterId := clusterIdResp.NodeClusterId
if clusterId == 0 {
this.Fail("当前用户没有指定集群,不能使用此服务")
}
for _, address := range addresses {
port := types.Int32(address.PortRange)
if port < 1024 || port > 65534 {
this.Fail("'" + address.PortRange + "' 端口范围错误")
}
resp, err := this.RPC().NodeClusterRPC().CheckPortIsUsingInNodeCluster(this.UserContext(), &pb.CheckPortIsUsingInNodeClusterRequest{
Port: port,
NodeClusterId: clusterId,
ExcludeServerId: params.ServerId,
ExcludeProtocol: "tls",
ProtocolFamily: "tcp",
})
if err != nil {
this.ErrorPage(err)
return
}
if resp.IsUsing {
this.Fail("端口 '" + fmt.Sprintf("%d", port) + "' 正在被别的服务或者同服务其他网络协议使用,请换一个")
}
}
// 校验SSL
var sslPolicyId = int64(0)
if params.SslPolicyJSON != nil {
sslPolicy := &sslconfigs.SSLPolicy{}
err = json.Unmarshal(params.SslPolicyJSON, sslPolicy)
if err != nil {
this.ErrorPage(errors.New("解析SSL配置时发生了错误" + err.Error()))
return
}
sslPolicyId = sslPolicy.Id
certsJSON, err := json.Marshal(sslPolicy.CertRefs)
if err != nil {
this.ErrorPage(err)
return
}
hstsJSON, err := json.Marshal(sslPolicy.HSTS)
if err != nil {
this.ErrorPage(err)
return
}
clientCACertsJSON, err := json.Marshal(sslPolicy.ClientCARefs)
if err != nil {
this.ErrorPage(err)
return
}
if sslPolicyId > 0 {
_, err := this.RPC().SSLPolicyRPC().UpdateSSLPolicy(this.UserContext(), &pb.UpdateSSLPolicyRequest{
SslPolicyId: sslPolicyId,
Http2Enabled: sslPolicy.HTTP2Enabled,
Http3Enabled: sslPolicy.HTTP3Enabled,
MinVersion: sslPolicy.MinVersion,
SslCertsJSON: certsJSON,
HstsJSON: hstsJSON,
ClientAuthType: types.Int32(sslPolicy.ClientAuthType),
ClientCACertsJSON: clientCACertsJSON,
CipherSuitesIsOn: sslPolicy.CipherSuitesIsOn,
CipherSuites: sslPolicy.CipherSuites,
})
if err != nil {
this.ErrorPage(err)
return
}
} else {
resp, err := this.RPC().SSLPolicyRPC().CreateSSLPolicy(this.UserContext(), &pb.CreateSSLPolicyRequest{
Http2Enabled: sslPolicy.HTTP2Enabled,
Http3Enabled: sslPolicy.HTTP3Enabled,
MinVersion: sslPolicy.MinVersion,
SslCertsJSON: certsJSON,
HstsJSON: hstsJSON,
ClientAuthType: types.Int32(sslPolicy.ClientAuthType),
ClientCACertsJSON: clientCACertsJSON,
CipherSuitesIsOn: sslPolicy.CipherSuitesIsOn,
CipherSuites: sslPolicy.CipherSuites,
})
if err != nil {
this.ErrorPage(err)
return
}
sslPolicyId = resp.SslPolicyId
}
}
tlsConfig := &serverconfigs.TLSProtocolConfig{}
if len(server.TlsJSON) > 0 {
err := json.Unmarshal(server.TlsJSON, tlsConfig)
if err != nil {
this.ErrorPage(err)
}
} else {
tlsConfig.IsOn = true
}
if canSpecifyPort {
tlsConfig.Listen = addresses
}
tlsConfig.SSLPolicyRef = &sslconfigs.SSLPolicyRef{
IsOn: true,
SSLPolicyId: sslPolicyId,
}
configData, err := json.Marshal(tlsConfig)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().ServerRPC().UpdateServerTLS(this.UserContext(), &pb.UpdateServerTLSRequest{
ServerId: params.ServerId,
TlsJSON: configData,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,18 @@
package tls
import (
"github.com/TeaOSLab/EdgeUser/internal/web/actions/default/lb/serverutils"
"github.com/TeaOSLab/EdgeUser/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth("")).
Helper(serverutils.NewServerHelper()).
Prefix("/lb/server/settings/tls").
GetPost("", new(IndexAction)).
EndAll()
})
}

View File

@@ -0,0 +1,144 @@
package udp
import (
"encoding/json"
"fmt"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/types"
)
// IndexAction UDP设置
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "setting", "index")
this.SecondMenu("udp")
}
func (this *IndexAction) RunGet(params struct {
ServerId int64
}) {
this.Data["canSpecifyPort"] = this.ValidateFeature(userconfigs.UserFeatureCodeServerUDPPort, params.ServerId)
server, err := dao.SharedServerDAO.FindEnabledServer(this.UserContext(), params.ServerId)
if err != nil {
this.ErrorPage(err)
return
}
if server == nil {
this.NotFound("server", params.ServerId)
return
}
udpConfig := &serverconfigs.UDPProtocolConfig{}
if len(server.UdpJSON) > 0 {
err := json.Unmarshal(server.UdpJSON, udpConfig)
if err != nil {
this.ErrorPage(err)
}
} else {
udpConfig.IsOn = true
}
this.Data["serverType"] = server.Type
this.Data["udpConfig"] = udpConfig
this.Show()
}
func (this *IndexAction) RunPost(params struct {
ServerId int64
ServerType string
Addresses string
Must *actions.Must
}) {
defer this.CreateLogInfo(codes.ServerUDP_LogUpdateUDPSettings, params.ServerId)
canSpecifyPort := this.ValidateFeature(userconfigs.UserFeatureCodeServerUDPPort, params.ServerId)
server, err := dao.SharedServerDAO.FindEnabledServer(this.UserContext(), params.ServerId)
if err != nil {
this.ErrorPage(err)
return
}
if server == nil {
this.NotFound("server", params.ServerId)
return
}
addresses := []*serverconfigs.NetworkAddressConfig{}
err = json.Unmarshal([]byte(params.Addresses), &addresses)
if err != nil {
this.Fail("端口地址解析失败:" + err.Error())
}
// 检查端口是否被使用
clusterIdResp, err := this.RPC().UserRPC().FindUserNodeClusterId(this.UserContext(), &pb.FindUserNodeClusterIdRequest{UserId: this.UserId()})
if err != nil {
this.ErrorPage(err)
return
}
clusterId := clusterIdResp.NodeClusterId
if clusterId == 0 {
this.Fail("当前用户没有指定集群,不能使用此服务")
}
for _, address := range addresses {
port := types.Int32(address.PortRange)
if port < 1024 || port > 65534 {
this.Fail("'" + address.PortRange + "' 端口范围错误")
}
resp, err := this.RPC().NodeClusterRPC().CheckPortIsUsingInNodeCluster(this.UserContext(), &pb.CheckPortIsUsingInNodeClusterRequest{
Port: port,
NodeClusterId: clusterId,
ExcludeServerId: params.ServerId,
ProtocolFamily: "udp",
})
if err != nil {
this.ErrorPage(err)
return
}
if resp.IsUsing {
this.Fail("端口 '" + fmt.Sprintf("%d", port) + "' 正在被别的服务或者同服务其他网络协议使用,请换一个")
}
}
udpConfig := &serverconfigs.UDPProtocolConfig{}
if len(server.UdpJSON) > 0 {
err := json.Unmarshal(server.UdpJSON, udpConfig)
if err != nil {
this.ErrorPage(err)
}
} else {
udpConfig.IsOn = true
}
if canSpecifyPort {
udpConfig.Listen = addresses
}
configData, err := json.Marshal(udpConfig)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().ServerRPC().UpdateServerUDP(this.UserContext(), &pb.UpdateServerUDPRequest{
ServerId: params.ServerId,
UdpJSON: configData,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,18 @@
package udp
import (
"github.com/TeaOSLab/EdgeUser/internal/web/actions/default/lb/serverutils"
"github.com/TeaOSLab/EdgeUser/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth("")).
Helper(serverutils.NewServerHelper()).
Prefix("/lb/server/settings/udp").
GetPost("", new(IndexAction)).
EndAll()
})
}