diff --git a/internal/rpc/rpc_client.go b/internal/rpc/rpc_client.go index 62d3935c..f70bb3ee 100644 --- a/internal/rpc/rpc_client.go +++ b/internal/rpc/rpc_client.go @@ -26,6 +26,8 @@ type RPCClient struct { serverClients []pb.ServerServiceClient apiNodeClients []pb.APINodeServiceClient originNodeClients []pb.OriginServerServiceClient + httpWebClients []pb.HTTPWebServiceClient + reverseProxyClients []pb.ReverseProxyServiceClient } func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) { @@ -41,6 +43,8 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) { serverClients := []pb.ServerServiceClient{} apiNodeClients := []pb.APINodeServiceClient{} originNodeClients := []pb.OriginServerServiceClient{} + httpWebClients := []pb.HTTPWebServiceClient{} + reverseProxyClients := []pb.ReverseProxyServiceClient{} conns := []*grpc.ClientConn{} for _, endpoint := range apiConfig.RPC.Endpoints { @@ -64,6 +68,8 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) { serverClients = append(serverClients, pb.NewServerServiceClient(conn)) apiNodeClients = append(apiNodeClients, pb.NewAPINodeServiceClient(conn)) originNodeClients = append(originNodeClients, pb.NewOriginServerServiceClient(conn)) + httpWebClients = append(httpWebClients, pb.NewHTTPWebServiceClient(conn)) + reverseProxyClients = append(reverseProxyClients, pb.NewReverseProxyServiceClient(conn)) } return &RPCClient{ @@ -76,6 +82,8 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) { serverClients: serverClients, apiNodeClients: apiNodeClients, originNodeClients: originNodeClients, + httpWebClients: httpWebClients, + reverseProxyClients: reverseProxyClients, }, nil } @@ -135,6 +143,20 @@ func (this *RPCClient) OriginServerRPC() pb.OriginServerServiceClient { return nil } +func (this *RPCClient) HTTPWebRPC() pb.HTTPWebServiceClient { + if len(this.httpWebClients) > 0 { + return this.httpWebClients[rands.Int(0, len(this.httpWebClients)-1)] + } + return nil +} + +func (this *RPCClient) ReverseProxyRPC() pb.ReverseProxyServiceClient { + if len(this.reverseProxyClients) > 0 { + return this.reverseProxyClients[rands.Int(0, len(this.reverseProxyClients)-1)] + } + return nil +} + func (this *RPCClient) Context(adminId int64) context.Context { ctx := context.Background() m := maps.Map{ diff --git a/internal/web/actions/default/servers/addOriginPopup.go b/internal/web/actions/default/servers/addOriginPopup.go index df254812..60dad1df 100644 --- a/internal/web/actions/default/servers/addOriginPopup.go +++ b/internal/web/actions/default/servers/addOriginPopup.go @@ -1,8 +1,8 @@ package servers import ( - "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/iwind/TeaGo/actions" "regexp" @@ -61,7 +61,7 @@ func (this *AddOriginPopupAction) RunPost(params struct { Id: resp.OriginId, IsOn: true, Addr: &serverconfigs.NetworkAddressConfig{ - Protocol: params.Protocol, + Protocol: serverconfigs.Protocol(params.Protocol), Host: host, PortRange: port, }, diff --git a/internal/web/actions/default/servers/create.go b/internal/web/actions/default/servers/create.go index 5b0590b7..7d778b49 100644 --- a/internal/web/actions/default/servers/create.go +++ b/internal/web/actions/default/servers/create.go @@ -66,13 +66,16 @@ func (this *CreateAction) RunPost(params struct { // TODO 验证集群ID - // 配置 - serverConfig := &serverconfigs.ServerConfig{} - serverConfig.IsOn = true - serverConfig.Name = params.Name - serverConfig.Description = params.Description - // 端口地址 + var httpConfig *serverconfigs.HTTPProtocolConfig = nil + var httpsConfig *serverconfigs.HTTPSProtocolConfig = nil + var tcpConfig *serverconfigs.TCPProtocolConfig = nil + var tlsConfig *serverconfigs.TLSProtocolConfig = nil + var unixConfig *serverconfigs.UnixProtocolConfig = nil + var udpConfig *serverconfigs.UDPProtocolConfig = nil + var webId int64 = 0 + var reverseProxyId int64 = 0 + switch params.ServerType { case serverconfigs.ServerTypeHTTPProxy, serverconfigs.ServerTypeHTTPWeb: listen := []*serverconfigs.NetworkAddressConfig{} @@ -80,27 +83,30 @@ func (this *CreateAction) RunPost(params struct { if err != nil { this.Fail("端口地址解析失败:" + err.Error()) } + if len(listen) == 0 { + this.Fail("至少需要绑定一个端口") + } for _, addr := range listen { - switch addr.Protocol { - case serverconfigs.ProtocolHTTP, serverconfigs.ProtocolHTTP4, serverconfigs.ProtocolHTTP6: - if serverConfig.HTTP == nil { - serverConfig.HTTP = &serverconfigs.HTTPProtocolConfig{ + switch addr.Protocol.Primary() { + case serverconfigs.ProtocolHTTP: + if httpConfig == nil { + httpConfig = &serverconfigs.HTTPProtocolConfig{ BaseProtocol: serverconfigs.BaseProtocol{ IsOn: true, }, } } - serverConfig.HTTP.AddListen(addr) - case serverconfigs.ProtocolHTTPS, serverconfigs.ProtocolHTTPS4, serverconfigs.ProtocolHTTPS6: - if serverConfig.HTTPS == nil { - serverConfig.HTTPS = &serverconfigs.HTTPSProtocolConfig{ + httpConfig.AddListen(addr) + case serverconfigs.ProtocolHTTPS: + if httpsConfig == nil { + httpsConfig = &serverconfigs.HTTPSProtocolConfig{ BaseProtocol: serverconfigs.BaseProtocol{ IsOn: true, }, } } - serverConfig.HTTPS.AddListen(addr) + httpsConfig.AddListen(addr) } } case serverconfigs.ServerTypeTCPProxy: @@ -109,27 +115,30 @@ func (this *CreateAction) RunPost(params struct { if err != nil { this.Fail("端口地址解析失败:" + err.Error()) } + if len(listen) == 0 { + this.Fail("至少需要绑定一个端口") + } for _, addr := range listen { - switch addr.Protocol { - case serverconfigs.ProtocolTCP, serverconfigs.ProtocolTCP4, serverconfigs.ProtocolTCP6: - if serverConfig.TCP == nil { - serverConfig.TCP = &serverconfigs.TCPProtocolConfig{ + switch addr.Protocol.Primary() { + case serverconfigs.ProtocolTCP: + if tcpConfig == nil { + tcpConfig = &serverconfigs.TCPProtocolConfig{ BaseProtocol: serverconfigs.BaseProtocol{ IsOn: true, }, } } - serverConfig.TCP.AddListen(addr) - case serverconfigs.ProtocolTLS, serverconfigs.ProtocolTLS4, serverconfigs.ProtocolTLS6: - if serverConfig.TLS == nil { - serverConfig.TLS = &serverconfigs.TLSProtocolConfig{ + tcpConfig.AddListen(addr) + case serverconfigs.ProtocolTLS: + if tlsConfig == nil { + tlsConfig = &serverconfigs.TLSProtocolConfig{ BaseProtocol: serverconfigs.BaseProtocol{ IsOn: true, }, } } - serverConfig.TLS.AddListen(addr) + tlsConfig.AddListen(addr) } } default: @@ -139,46 +148,44 @@ func (this *CreateAction) RunPost(params struct { // TODO 证书 // 域名 - serverNames := []*serverconfigs.ServerNameConfig{} - err := json.Unmarshal([]byte(params.ServerNames), &serverNames) - if err != nil { - this.Fail("域名解析失败:" + err.Error()) + if len(params.ServerNames) > 0 { + serverNames := []*serverconfigs.ServerNameConfig{} + err := json.Unmarshal([]byte(params.ServerNames), &serverNames) + if err != nil { + this.Fail("域名解析失败:" + err.Error()) + } } - serverConfig.ServerNames = serverNames // 源站地址 switch params.ServerType { case serverconfigs.ServerTypeHTTPProxy, serverconfigs.ServerTypeTCPProxy: origins := []*serverconfigs.OriginServerConfig{} - err = json.Unmarshal([]byte(params.Origins), &origins) + err := json.Unmarshal([]byte(params.Origins), &origins) if err != nil { this.Fail("源站地址解析失败:" + err.Error()) } - serverConfig.ReverseProxy = &serverconfigs.ReverseProxyConfig{ - IsOn: true, - Origins: origins, + + resp, err := this.RPC().ReverseProxyRPC().CreateReverseProxy(this.AdminContext(), &pb.CreateReverseProxyRequest{ + SchedulingJSON: nil, + PrimaryOriginsJSON: []byte(params.Origins), + BackupOriginsJSON: nil, + }) + if err != nil { + this.ErrorPage(err) + return } + reverseProxyId = resp.ReverseProxyId } // Web地址 switch params.ServerType { case serverconfigs.ServerTypeHTTPWeb: - serverConfig.Web = &serverconfigs.WebConfig{ - IsOn: true, - Root: params.WebRoot, + webResp, err := this.RPC().HTTPWebRPC().CreateHTTPWeb(this.AdminContext(), &pb.CreateHTTPWebRequest{Root: params.WebRoot}) + if err != nil { + this.ErrorPage(err) + return } - } - - // 校验 - err = serverConfig.Init() - if err != nil { - this.Fail("配置校验失败:" + err.Error()) - } - - serverConfigJSON, err := serverConfig.AsJSON() - if err != nil { - this.ErrorPage(err) - return + webId = webResp.WebId } // 包含条件 @@ -197,17 +204,68 @@ func (this *CreateAction) RunPost(params struct { return } - _, err = this.RPC().ServerRPC().CreateServer(this.AdminContext(), &pb.CreateServerRequest{ + req := &pb.CreateServerRequest{ UserId: 0, AdminId: this.AdminId(), Type: params.ServerType, Name: params.Name, + ServerNamesJON: []byte(params.ServerNames), Description: params.Description, ClusterId: params.ClusterId, - Config: serverConfigJSON, IncludeNodesJSON: includeNodesJSON, ExcludeNodesJSON: excludeNodesJSON, - }) + WebId: webId, + ReverseProxyId: reverseProxyId, + } + if httpConfig != nil { + data, err := json.Marshal(httpConfig) + if err != nil { + this.ErrorPage(err) + return + } + req.HttpJSON = data + } + if httpsConfig != nil { + data, err := json.Marshal(httpsConfig) + if err != nil { + this.ErrorPage(err) + return + } + req.HttpsJSON = data + } + if tcpConfig != nil { + data, err := json.Marshal(tcpConfig) + if err != nil { + this.ErrorPage(err) + return + } + req.TcpJSON = data + } + if tlsConfig != nil { + data, err := json.Marshal(tlsConfig) + if err != nil { + this.ErrorPage(err) + return + } + req.TlsJSON = data + } + if unixConfig != nil { + data, err := json.Marshal(unixConfig) + if err != nil { + this.ErrorPage(err) + return + } + req.UnixJSON = data + } + if udpConfig != nil { + data, err := json.Marshal(udpConfig) + if err != nil { + this.ErrorPage(err) + return + } + req.UdpJSON = data + } + _, err = this.RPC().ServerRPC().CreateServer(this.AdminContext(), req) if err != nil { this.ErrorPage(err) return diff --git a/internal/web/actions/default/servers/index.go b/internal/web/actions/default/servers/index.go index c82a2b75..78bebf10 100644 --- a/internal/web/actions/default/servers/index.go +++ b/internal/web/actions/default/servers/index.go @@ -2,12 +2,10 @@ package servers import ( "encoding/json" - "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" - "github.com/iwind/TeaGo/logs" "github.com/iwind/TeaGo/maps" - "strings" ) type IndexAction struct { @@ -39,70 +37,57 @@ func (this *IndexAction) RunGet(params struct{}) { } serverMaps := []maps.Map{} for _, server := range serversResp.Servers { - // 服务名 - serverConfig := &serverconfigs.ServerConfig{} - err = json.Unmarshal(server.Config, &serverConfig) + config := &serverconfigs.ServerConfig{} + err = json.Unmarshal(server.Config, config) if err != nil { this.ErrorPage(err) return } - err = serverConfig.Init() - if err != nil { - logs.Println("init server '" + serverConfig.Name + "' error: " + err.Error()) - } - - serverTypeNames := []string{} // 端口列表 portMaps := []maps.Map{} - if serverConfig.HTTP != nil && serverConfig.HTTP.IsOn { - serverTypeNames = append(serverTypeNames, "HTTP") - for _, listen := range serverConfig.HTTP.Listen { + if len(server.HttpJSON) > 0 && config.HTTP.IsOn { + for _, listen := range config.HTTP.Listen { portMaps = append(portMaps, maps.Map{ "protocol": listen.Protocol, "portRange": listen.PortRange, }) } } - if serverConfig.HTTPS != nil && serverConfig.HTTPS.IsOn { - serverTypeNames = append(serverTypeNames, "HTTPS") - for _, listen := range serverConfig.HTTPS.Listen { + if config.HTTPS != nil && config.HTTPS.IsOn { + for _, listen := range config.HTTPS.Listen { portMaps = append(portMaps, maps.Map{ "protocol": listen.Protocol, "portRange": listen.PortRange, }) } } - if serverConfig.TCP != nil && serverConfig.TCP.IsOn { - serverTypeNames = append(serverTypeNames, "TCP") - for _, listen := range serverConfig.TCP.Listen { + if config.TCP != nil && config.TCP.IsOn { + for _, listen := range config.TCP.Listen { portMaps = append(portMaps, maps.Map{ "protocol": listen.Protocol, "portRange": listen.PortRange, }) } } - if serverConfig.TLS != nil && serverConfig.TLS.IsOn { - serverTypeNames = append(serverTypeNames, "TLS") - for _, listen := range serverConfig.TLS.Listen { + if config.TLS != nil && config.TLS.IsOn { + for _, listen := range config.TLS.Listen { portMaps = append(portMaps, maps.Map{ "protocol": listen.Protocol, "portRange": listen.PortRange, }) } } - if serverConfig.Unix != nil && serverConfig.Unix.IsOn { - serverTypeNames = append(serverTypeNames, "Unix") - for _, listen := range serverConfig.Unix.Listen { + if config.Unix != nil && config.Unix.IsOn { + for _, listen := range config.Unix.Listen { portMaps = append(portMaps, maps.Map{ "protocol": listen.Protocol, "portRange": listen.Host, }) } } - if serverConfig.UDP != nil && serverConfig.UDP.IsOn { - serverTypeNames = append(serverTypeNames, "UDP") - for _, listen := range serverConfig.UDP.Listen { + if config.UDP != nil && config.UDP.IsOn { + for _, listen := range config.UDP.Listen { portMaps = append(portMaps, maps.Map{ "protocol": listen.Protocol, "portRange": listen.PortRange, @@ -118,7 +103,7 @@ func (this *IndexAction) RunGet(params struct{}) { "name": server.Cluster.Name, }, "ports": portMaps, - "serverTypeName": strings.Join(serverTypeNames, "+"), + "serverTypeName": serverconfigs.FindServerType(server.Type).GetString("name"), }) } this.Data["servers"] = serverMaps diff --git a/internal/web/actions/default/servers/server/settings/origins/addPopup.go b/internal/web/actions/default/servers/server/settings/origins/addPopup.go new file mode 100644 index 00000000..b37f8d01 --- /dev/null +++ b/internal/web/actions/default/servers/server/settings/origins/addPopup.go @@ -0,0 +1,140 @@ +package origins + +import ( + "encoding/json" + "errors" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/iwind/TeaGo/actions" + "regexp" + "strings" +) + +// 添加源站 +type AddPopupAction struct { + actionutils.ParentAction +} + +func (this *AddPopupAction) RunGet(params struct { + ServerId int64 + ReverseProxyId int64 + OriginType string +}) { + this.Data["reverseProxyId"] = params.ReverseProxyId + this.Data["originType"] = params.OriginType + + serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{ServerId: params.ServerId}) + if err != nil { + this.ErrorPage(err) + return + } + serverType := serverTypeResp.Type + this.Data["serverType"] = serverType + + this.Show() +} + +func (this *AddPopupAction) RunPost(params struct { + OriginType string + + ReverseProxyId int64 + Protocol string + Addr string + + Must *actions.Must +}) { + params.Must. + Field("addr", params.Addr). + Require("请输入源站地址") + + addr := regexp.MustCompile(`\s+`).ReplaceAllString(params.Addr, "") + portIndex := strings.LastIndex(params.Addr, ":") + if portIndex < 0 { + this.Fail("地址中需要带有端口") + } + host := addr[:portIndex] + port := addr[portIndex+1:] + + resp, err := this.RPC().OriginServerRPC().CreateOriginServer(this.AdminContext(), &pb.CreateOriginServerRequest{ + Name: "", + Addr: &pb.NetworkAddress{ + Protocol: params.Protocol, + Host: host, + PortRange: port, + }, + Description: "", + }) + if err != nil { + this.ErrorPage(err) + return + } + originId := resp.OriginId + originConfigResp, err := this.RPC().OriginServerRPC().FindEnabledOriginServerConfig(this.AdminContext(), &pb.FindEnabledOriginServerConfigRequest{OriginId: originId}) + if err != nil { + this.ErrorPage(err) + return + } + originConfigData := originConfigResp.Config + var originConfig = &serverconfigs.OriginServerConfig{} + err = json.Unmarshal(originConfigData, originConfig) + if err != nil { + this.ErrorPage(err) + return + } + + reverseProxyResp, err := this.RPC().ReverseProxyRPC().FindEnabledReverseProxy(this.AdminContext(), &pb.FindEnabledReverseProxyRequest{ReverseProxyId: params.ReverseProxyId}) + if err != nil { + this.ErrorPage(err) + return + } + reverseProxy := reverseProxyResp.ReverseProxy + if reverseProxy == nil { + this.ErrorPage(errors.New("reverse proxy should not be nil")) + return + } + + origins := []*serverconfigs.OriginServerConfig{} + switch params.OriginType { + case "primary": + if len(reverseProxy.PrimaryOriginsJSON) > 0 { + err = json.Unmarshal(reverseProxy.PrimaryOriginsJSON, &origins) + if err != nil { + this.ErrorPage(err) + return + } + } + case "backup": + if len(reverseProxy.BackupOriginsJSON) > 0 { + err = json.Unmarshal(reverseProxy.BackupOriginsJSON, &origins) + if err != nil { + this.ErrorPage(err) + return + } + } + } + origins = append(origins, originConfig) + originsData, err := json.Marshal(origins) + if err != nil { + this.ErrorPage(err) + return + } + switch params.OriginType { + case "primary": + _, err = this.RPC().ReverseProxyRPC().UpdateReverseProxyPrimaryOrigins(this.AdminContext(), &pb.UpdateReverseProxyPrimaryOriginsRequest{ + ReverseProxyId: params.ReverseProxyId, + OriginsJSON: originsData, + }) + case "backup": + _, err = this.RPC().ReverseProxyRPC().UpdateReverseProxyBackupOrigins(this.AdminContext(), &pb.UpdateReverseProxyBackupOriginsRequest{ + ReverseProxyId: params.ReverseProxyId, + OriginsJSON: originsData, + }) + } + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/actions/default/servers/server/settings/origins/delete.go b/internal/web/actions/default/servers/server/settings/origins/delete.go new file mode 100644 index 00000000..4913848a --- /dev/null +++ b/internal/web/actions/default/servers/server/settings/origins/delete.go @@ -0,0 +1,85 @@ +package origins + +import ( + "encoding/json" + "errors" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" +) + +type DeleteAction struct { + actionutils.ParentAction +} + +func (this *DeleteAction) RunPost(params struct { + ReverseProxyId int64 + OriginId int64 + OriginType string +}) { + reverseProxyResp, err := this.RPC().ReverseProxyRPC().FindEnabledReverseProxy(this.AdminContext(), &pb.FindEnabledReverseProxyRequest{ReverseProxyId: params.ReverseProxyId}) + if err != nil { + this.ErrorPage(err) + return + } + reverseProxy := reverseProxyResp.ReverseProxy + if reverseProxy == nil { + this.ErrorPage(errors.New("reverse proxy is nil")) + return + } + + origins := []*serverconfigs.OriginServerConfig{} + switch params.OriginType { + case "primary": + err = json.Unmarshal(reverseProxy.PrimaryOriginsJSON, &origins) + if err != nil { + this.ErrorPage(err) + return + } + case "backup": + err = json.Unmarshal(reverseProxy.BackupOriginsJSON, &origins) + if err != nil { + this.ErrorPage(err) + return + } + default: + this.ErrorPage(errors.New("invalid origin type '" + params.OriginType + "'")) + return + } + + result := []*serverconfigs.OriginServerConfig{} + for _, origin := range origins { + if origin.Id == params.OriginId { + continue + } + result = append(result, origin) + } + resultData, err := json.Marshal(result) + if err != nil { + this.ErrorPage(err) + return + } + + switch params.OriginType { + case "primary": + _, err = this.RPC().ReverseProxyRPC().UpdateReverseProxyPrimaryOrigins(this.AdminContext(), &pb.UpdateReverseProxyPrimaryOriginsRequest{ + ReverseProxyId: params.ReverseProxyId, + OriginsJSON: resultData, + }) + if err != nil { + this.ErrorPage(err) + return + } + case "backup": + _, err = this.RPC().ReverseProxyRPC().UpdateReverseProxyBackupOrigins(this.AdminContext(), &pb.UpdateReverseProxyBackupOriginsRequest{ + ReverseProxyId: params.ReverseProxyId, + OriginsJSON: resultData, + }) + if err != nil { + this.ErrorPage(err) + return + } + } + + this.Success() +} diff --git a/internal/web/actions/default/servers/server/settings/origins/init.go b/internal/web/actions/default/servers/server/settings/origins/init.go new file mode 100644 index 00000000..ab1f2539 --- /dev/null +++ b/internal/web/actions/default/servers/server/settings/origins/init.go @@ -0,0 +1,18 @@ +package origins + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/helpers" + "github.com/iwind/TeaGo" +) + +func init() { + TeaGo.BeforeStart(func(server *TeaGo.Server) { + server. + Helper(helpers.NewUserMustAuth()). + Prefix("/servers/server/settings/origins"). + GetPost("/addPopup", new(AddPopupAction)). + Post("/delete", new(DeleteAction)). + GetPost("/updatePopup", new(UpdatePopupAction)). + EndAll() + }) +} diff --git a/internal/web/actions/default/servers/server/settings/origins/updatePopup.go b/internal/web/actions/default/servers/server/settings/origins/updatePopup.go new file mode 100644 index 00000000..08c75986 --- /dev/null +++ b/internal/web/actions/default/servers/server/settings/origins/updatePopup.go @@ -0,0 +1,178 @@ +package origins + +import ( + "encoding/json" + "errors" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/iwind/TeaGo/actions" + "github.com/iwind/TeaGo/maps" + "regexp" + "strings" +) + +// 修改源站 +type UpdatePopupAction struct { + actionutils.ParentAction +} + +func (this *UpdatePopupAction) Init() { + this.Nav("", "", "") +} + +func (this *UpdatePopupAction) RunGet(params struct { + ServerId int64 + ReverseProxyId int64 + OriginType string + OriginId int64 +}) { + this.Data["originType"] = params.OriginType + this.Data["reverseProxyId"] = params.ReverseProxyId + this.Data["originId"] = params.OriginId + + serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{ + ServerId: params.ServerId, + }) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["serverType"] = serverTypeResp.Type + + // 源站信息 + originResp, err := this.RPC().OriginServerRPC().FindEnabledOriginServerConfig(this.AdminContext(), &pb.FindEnabledOriginServerConfigRequest{OriginId: params.OriginId}) + if err != nil { + this.ErrorPage(err) + return + } + configData := originResp.Config + config := &serverconfigs.OriginServerConfig{} + err = json.Unmarshal(configData, config) + if err != nil { + this.ErrorPage(err) + return + } + + this.Data["origin"] = maps.Map{ + "id": config.Id, + "protocol": config.Addr.Protocol, + "addr": config.Addr.Host + ":" + config.Addr.PortRange, + } + + this.Show() +} + +func (this *UpdatePopupAction) RunPost(params struct { + OriginType string + OriginId int64 + + ReverseProxyId int64 + Protocol string + Addr string + + Must *actions.Must +}) { + params.Must. + Field("addr", params.Addr). + Require("请输入源站地址") + + addr := regexp.MustCompile(`\s+`).ReplaceAllString(params.Addr, "") + portIndex := strings.LastIndex(params.Addr, ":") + if portIndex < 0 { + this.Fail("地址中需要带有端口") + } + host := addr[:portIndex] + port := addr[portIndex+1:] + + _, err := this.RPC().OriginServerRPC().UpdateOriginServer(this.AdminContext(), &pb.UpdateOriginServerRequest{ + OriginId: params.OriginId, + Name: "", + Addr: &pb.NetworkAddress{ + Protocol: params.Protocol, + Host: host, + PortRange: port, + }, + Description: "", + }) + if err != nil { + this.ErrorPage(err) + return + } + + originConfigResp, err := this.RPC().OriginServerRPC().FindEnabledOriginServerConfig(this.AdminContext(), &pb.FindEnabledOriginServerConfigRequest{OriginId: params.OriginId}) + if err != nil { + this.ErrorPage(err) + return + } + originConfigData := originConfigResp.Config + var originConfig = &serverconfigs.OriginServerConfig{} + err = json.Unmarshal(originConfigData, originConfig) + if err != nil { + this.ErrorPage(err) + return + } + + // 查找反向代理信息 + reverseProxyResp, err := this.RPC().ReverseProxyRPC().FindEnabledReverseProxy(this.AdminContext(), &pb.FindEnabledReverseProxyRequest{ReverseProxyId: params.ReverseProxyId}) + if err != nil { + this.ErrorPage(err) + return + } + reverseProxy := reverseProxyResp.ReverseProxy + if reverseProxy == nil { + this.ErrorPage(errors.New("reverse proxy should not be nil")) + return + } + + origins := []*serverconfigs.OriginServerConfig{} + switch params.OriginType { + case "primary": + if len(reverseProxy.PrimaryOriginsJSON) > 0 { + err = json.Unmarshal(reverseProxy.PrimaryOriginsJSON, &origins) + if err != nil { + this.ErrorPage(err) + return + } + } + case "backup": + if len(reverseProxy.BackupOriginsJSON) > 0 { + err = json.Unmarshal(reverseProxy.BackupOriginsJSON, &origins) + if err != nil { + this.ErrorPage(err) + return + } + } + } + + for index, origin := range origins { + if origin.Id == params.OriginId { + origins[index] = originConfig + } + } + + // 保存 + originsData, err := json.Marshal(origins) + if err != nil { + this.ErrorPage(err) + return + } + switch params.OriginType { + case "primary": + _, err = this.RPC().ReverseProxyRPC().UpdateReverseProxyPrimaryOrigins(this.AdminContext(), &pb.UpdateReverseProxyPrimaryOriginsRequest{ + ReverseProxyId: params.ReverseProxyId, + OriginsJSON: originsData, + }) + case "backup": + _, err = this.RPC().ReverseProxyRPC().UpdateReverseProxyBackupOrigins(this.AdminContext(), &pb.UpdateReverseProxyBackupOriginsRequest{ + ReverseProxyId: params.ReverseProxyId, + OriginsJSON: originsData, + }) + } + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/actions/default/servers/server/settings/reverseProxy/index.go b/internal/web/actions/default/servers/server/settings/reverseProxy/index.go index 7cafb19a..ca139eb4 100644 --- a/internal/web/actions/default/servers/server/settings/reverseProxy/index.go +++ b/internal/web/actions/default/servers/server/settings/reverseProxy/index.go @@ -1,22 +1,89 @@ package reverseProxy import ( + "encoding/json" + "errors" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/serverutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/iwind/TeaGo/maps" ) +// 源站列表 type IndexAction struct { actionutils.ParentAction } func (this *IndexAction) Init() { - this.Nav("", "setting", "index") - this.SecondMenu("reverseProxy") + this.FirstMenu("index") } func (this *IndexAction) RunGet(params struct { ServerId int64 }) { - // TODO + server, _, isOk := serverutils.FindServer(&this.ParentAction, params.ServerId) + if !isOk { + return + } + this.Data["serverType"] = server.Type + this.Data["reverseProxyId"] = server.ReverseProxyId + + if server.ReverseProxyId <= 0 { + // TODO 应该在界面上提示用户开启 + this.ErrorPage(errors.New("reverse proxy should not be nil")) + return + } + + reverseProxyResp, err := this.RPC().ReverseProxyRPC().FindEnabledReverseProxy(this.AdminContext(), &pb.FindEnabledReverseProxyRequest{ReverseProxyId: server.ReverseProxyId}) + if err != nil { + this.ErrorPage(err) + return + } + reverseProxy := reverseProxyResp.ReverseProxy + if reverseProxy == nil { + // TODO 应该在界面上提示用户开启 + this.ErrorPage(errors.New("reverse proxy should not be nil")) + return + } + + primaryOrigins := []*serverconfigs.OriginServerConfig{} + backupOrigins := []*serverconfigs.OriginServerConfig{} + if len(reverseProxy.PrimaryOriginsJSON) > 0 { + err = json.Unmarshal(reverseProxy.PrimaryOriginsJSON, &primaryOrigins) + if err != nil { + this.ErrorPage(err) + return + } + } + if len(reverseProxy.BackupOriginsJSON) > 0 { + err = json.Unmarshal(reverseProxy.BackupOriginsJSON, &backupOrigins) + if err != nil { + this.ErrorPage(err) + return + } + } + + primaryOriginMaps := []maps.Map{} + backupOriginMaps := []maps.Map{} + for _, originConfig := range primaryOrigins { + m := maps.Map{ + "id": originConfig.Id, + "weight": originConfig.Weight, + "addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange, + } + primaryOriginMaps = append(primaryOriginMaps, m) + } + for _, originConfig := range backupOrigins { + m := maps.Map{ + "id": originConfig.Id, + "weight": originConfig.Weight, + "addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange, + } + backupOriginMaps = append(backupOriginMaps, m) + } + this.Data["primaryOrigins"] = primaryOriginMaps + this.Data["backupOrigins"] = backupOriginMaps this.Show() } diff --git a/internal/web/actions/default/servers/server/settings/reverseProxy/init.go b/internal/web/actions/default/servers/server/settings/reverseProxy/init.go index 89836fde..897a55da 100644 --- a/internal/web/actions/default/servers/server/settings/reverseProxy/init.go +++ b/internal/web/actions/default/servers/server/settings/reverseProxy/init.go @@ -11,8 +11,12 @@ func init() { server. Helper(helpers.NewUserMustAuth()). Helper(serverutils.NewServerHelper()). + Data("mainTab", "setting"). + Data("secondMenuItem", "reverseProxy"). Prefix("/servers/server/settings/reverseProxy"). Get("", new(IndexAction)). + GetPost("/scheduling", new(SchedulingAction)). + GetPost("/updateSchedulingPopup", new(UpdateSchedulingPopupAction)). EndAll() }) } diff --git a/internal/web/actions/default/servers/server/settings/reverseProxy/scheduling.go b/internal/web/actions/default/servers/server/settings/reverseProxy/scheduling.go new file mode 100644 index 00000000..cb2c81a8 --- /dev/null +++ b/internal/web/actions/default/servers/server/settings/reverseProxy/scheduling.go @@ -0,0 +1,59 @@ +package reverseProxy + +import ( + "encoding/json" + "errors" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/serverutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/schedulingconfigs" +) + +type SchedulingAction struct { + actionutils.ParentAction +} + +func (this *SchedulingAction) Init() { + this.FirstMenu("scheduling") +} + +func (this *SchedulingAction) RunGet(params struct { + ServerId int64 +}) { + server, _, isOk := serverutils.FindServer(&this.ParentAction, params.ServerId) + if !isOk { + return + } + + if server.ReverseProxyId <= 0 { + // TODO 在界面上提示用户未开通,并提供开通按钮,用户点击后开通 + this.WriteString("此服务尚未开通反向代理功能") + return + } + this.Data["reverseProxyId"] = server.ReverseProxyId + + reverseProxyResp, err := this.RPC().ReverseProxyRPC().FindEnabledReverseProxyConfig(this.AdminContext(), &pb.FindEnabledReverseProxyConfigRequest{ + ReverseProxyId: server.ReverseProxyId, + }) + if err != nil { + this.ErrorPage(err) + return + } + reverseProxy := &serverconfigs.ReverseProxyConfig{} + err = json.Unmarshal(reverseProxyResp.Config, reverseProxy) + if err != nil { + this.ErrorPage(err) + return + } + + 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() +} diff --git a/internal/web/actions/default/servers/server/settings/reverseProxy/updateSchedulingPopup.go b/internal/web/actions/default/servers/server/settings/reverseProxy/updateSchedulingPopup.go new file mode 100644 index 00000000..5dc26437 --- /dev/null +++ b/internal/web/actions/default/servers/server/settings/reverseProxy/updateSchedulingPopup.go @@ -0,0 +1,155 @@ +package reverseProxy + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/serverutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/schedulingconfigs" + "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 +}) { + this.Data["dataType"] = params.Type + this.Data["serverId"] = params.ServerId + this.Data["reverseProxyId"] = params.ReverseProxyId + + _, serverConfig, isOk := serverutils.FindServer(&this.ParentAction, params.ServerId) + if !isOk { + return + } + + reverseProxyResp, err := this.RPC().ReverseProxyRPC().FindEnabledReverseProxyConfig(this.AdminContext(), &pb.FindEnabledReverseProxyConfigRequest{ + ReverseProxyId: params.ReverseProxyId, + }) + if err != nil { + this.ErrorPage(err) + return + } + configData := reverseProxyResp.Config + + 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.IsHTTP() && lists.Contains(networks, "http")) || + (serverConfig.IsTCP() && lists.Contains(networks, "tcp")) || + (serverConfig.IsUDP() && lists.Contains(networks, "udp")) || + (serverConfig.IsUnix() && lists.Contains(networks, "unix")) { + 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 +}) { + reverseProxyResp, err := this.RPC().ReverseProxyRPC().FindEnabledReverseProxyConfig(this.AdminContext(), &pb.FindEnabledReverseProxyConfigRequest{ReverseProxyId: params.ReverseProxyId}) + if err != nil { + this.ErrorPage(err) + return + } + configData := reverseProxyResp.Config + 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.AdminContext(), &pb.UpdateReverseProxySchedulingRequest{ + ReverseProxyId: params.ReverseProxyId, + SchedulingJSON: schedulingData, + }) + if err != nil { + this.ErrorPage(err) + } + + this.Success() +} diff --git a/internal/web/actions/default/servers/server/settings/tcp/index.go b/internal/web/actions/default/servers/server/settings/tcp/index.go index bcc90805..a96ef9bb 100644 --- a/internal/web/actions/default/servers/server/settings/tcp/index.go +++ b/internal/web/actions/default/servers/server/settings/tcp/index.go @@ -49,40 +49,201 @@ func (this *IndexAction) RunPost(params struct { Must *actions.Must }) { - _, config, isOk := serverutils.FindServer(&this.ParentAction, params.ServerId) + serverId := params.ServerId + + server, _, isOk := serverutils.FindServer(&this.ParentAction, params.ServerId) if !isOk { return } - listen := []*serverconfigs.NetworkAddressConfig{} - err := json.Unmarshal([]byte(params.Addresses), &listen) + addresses := []*serverconfigs.NetworkAddressConfig{} + err := json.Unmarshal([]byte(params.Addresses), &addresses) if err != nil { this.Fail("端口地址解析失败:" + err.Error()) } - if config.IsHTTP() { - config.HTTP.Listen = listen - } else if config.IsTCP() { - config.TCP.Listen = listen - } else if config.IsUnix() { - config.Unix.Listen = listen - } else if config.IsUDP() { - config.UDP.Listen = listen - } + switch server.Type { + case serverconfigs.ServerTypeHTTPProxy, serverconfigs.ServerTypeHTTPWeb: + var httpConfig = &serverconfigs.HTTPProtocolConfig{} + if len(server.HttpJSON) > 0 { + err = json.Unmarshal(server.HttpJSON, httpConfig) + if err != nil { + this.ErrorPage(err) + return + } + httpConfig.Listen = []*serverconfigs.NetworkAddressConfig{} + } else { + httpConfig.IsOn = true + } - configData, err := config.AsJSON() - if err != nil { - this.ErrorPage(err) - return - } + var httpsConfig = &serverconfigs.HTTPSProtocolConfig{} + if len(server.HttpsJSON) > 0 { + err = json.Unmarshal(server.HttpsJSON, httpsConfig) + if err != nil { + this.ErrorPage(err) + return + } + httpsConfig.Listen = []*serverconfigs.NetworkAddressConfig{} + } else { + httpsConfig.IsOn = true + } - _, err = this.RPC().ServerRPC().UpdateServerConfig(this.AdminContext(), &pb.UpdateServerConfigRequest{ - ServerId: params.ServerId, - Config: configData, - }) - if err != nil { - this.ErrorPage(err) - return + for _, addr := range addresses { + switch addr.Protocol.Primary() { + case serverconfigs.ProtocolHTTP: + httpConfig.AddListen(addr) + case serverconfigs.ProtocolHTTPS: + httpsConfig.AddListen(addr) + } + } + + httpData, err := json.Marshal(httpConfig) + if err != nil { + this.ErrorPage(err) + return + } + httpsData, err := json.Marshal(httpsConfig) + if err != nil { + this.ErrorPage(err) + return + } + _, err = this.RPC().ServerRPC().UpdateServerHTTP(this.AdminContext(), &pb.UpdateServerHTTPRequest{ + ServerId: serverId, + Config: httpData, + }) + if err != nil { + this.ErrorPage(err) + return + } + _, err = this.RPC().ServerRPC().UpdateServerHTTPS(this.AdminContext(), &pb.UpdateServerHTTPSRequest{ + ServerId: serverId, + Config: httpsData, + }) + if err != nil { + this.ErrorPage(err) + return + } + case serverconfigs.ServerTypeTCPProxy: + tcpProxy := &serverconfigs.TCPProtocolConfig{} + if len(server.TcpJSON) > 0 { + err = json.Unmarshal(server.TcpJSON, tcpProxy) + if err != nil { + this.ErrorPage(err) + return + } + tcpProxy.Listen = []*serverconfigs.NetworkAddressConfig{} + } else { + tcpProxy.IsOn = true + } + + tlsProxy := &serverconfigs.TLSProtocolConfig{} + if len(server.TlsJSON) > 0 { + err = json.Unmarshal(server.TlsJSON, tlsProxy) + if err != nil { + this.ErrorPage(err) + return + } + tlsProxy.Listen = []*serverconfigs.NetworkAddressConfig{} + } else { + tlsProxy.IsOn = true + } + + for _, addr := range addresses { + switch addr.Protocol.Primary() { + case serverconfigs.ProtocolTCP: + tcpProxy.AddListen(addr) + case serverconfigs.ProtocolTLS: + tlsProxy.AddListen(addr) + } + } + + tcpData, err := json.Marshal(tcpProxy) + if err != nil { + this.ErrorPage(err) + return + } + + tlsData, err := json.Marshal(tlsProxy) + if err != nil { + this.ErrorPage(err) + return + } + + _, err = this.RPC().ServerRPC().UpdateServerTCP(this.AdminContext(), &pb.UpdateServerTCPRequest{ + ServerId: serverId, + Config: tcpData, + }) + if err != nil { + this.ErrorPage(err) + return + } + + _, err = this.RPC().ServerRPC().UpdateServerTLS(this.AdminContext(), &pb.UpdateServerTLSRequest{ + ServerId: serverId, + Config: tlsData, + }) + if err != nil { + this.ErrorPage(err) + return + } + case serverconfigs.ServerTypeUnixProxy: + unixConfig := &serverconfigs.UnixProtocolConfig{} + if len(server.UnixJSON) > 0 { + err = json.Unmarshal(server.UnixJSON, unixConfig) + if err != nil { + this.ErrorPage(err) + return + } + unixConfig.Listen = []*serverconfigs.NetworkAddressConfig{} + } + for _, addr := range addresses { + switch addr.Protocol.Primary() { + case serverconfigs.ProtocolUnix: + unixConfig.AddListen(addr) + } + } + unixData, err := json.Marshal(unixConfig) + if err != nil { + this.ErrorPage(err) + return + } + _, err = this.RPC().ServerRPC().UpdateServerUnix(this.AdminContext(), &pb.UpdateServerUnixRequest{ + ServerId: serverId, + Config: unixData, + }) + if err != nil { + this.ErrorPage(err) + return + } + case serverconfigs.ServerTypeUDPProxy: + udpConfig := &serverconfigs.UDPProtocolConfig{} + if len(server.UdpJSON) > 0 { + err = json.Unmarshal(server.UdpJSON, udpConfig) + if err != nil { + this.ErrorPage(err) + return + } + udpConfig.Listen = []*serverconfigs.NetworkAddressConfig{} + } + for _, addr := range addresses { + switch addr.Protocol.Primary() { + case serverconfigs.ProtocolUDP: + udpConfig.AddListen(addr) + } + } + udpData, err := json.Marshal(udpConfig) + if err != nil { + this.ErrorPage(err) + return + } + _, err = this.RPC().ServerRPC().UpdateServerUDP(this.AdminContext(), &pb.UpdateServerUDPRequest{ + ServerId: serverId, + Config: udpData, + }) + if err != nil { + this.ErrorPage(err) + return + } } this.Success() diff --git a/internal/web/import.go b/internal/web/import.go index e70e3382..4a2fc80b 100644 --- a/internal/web/import.go +++ b/internal/web/import.go @@ -35,6 +35,7 @@ import ( _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/http" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/https" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/locations" + _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/origins" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/pages" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/reverseProxy" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/stat" diff --git a/web/public/js/components/server/origin-list-box.js b/web/public/js/components/server/origin-list-box.js new file mode 100644 index 00000000..659e3610 --- /dev/null +++ b/web/public/js/components/server/origin-list-box.js @@ -0,0 +1,84 @@ +Vue.component("origin-list-box", { + props: ["v-primary-origins", "v-backup-origins", "v-server-type", "v-params"], + data: function () { + return { + primaryOrigins: this.vPrimaryOrigins, + backupOrigins: this.vBackupOrigins + } + }, + methods: { + createPrimaryOrigin: function () { + teaweb.popup("/servers/server/settings/origins/addPopup?originType=primary&" + this.vParams, { + callback: function (resp) { + window.location.reload() + } + }) + }, + createBackupOrigin: function () { + teaweb.popup("/servers/server/settings/origins/addPopup?originType=backup&" + this.vParams, { + callback: function (resp) { + window.location.reload() + } + }) + }, + updateOrigin: function (originId, originType) { + teaweb.popup("/servers/server/settings/origins/updatePopup?originType=" + originType + "&" + this.vParams + "&originId=" + originId, { + callback: function (resp) { + window.location.reload() + } + }) + }, + deleteOrigin: function (originId, originType) { + let that = this + teaweb.confirm("确定要删除此源站吗?", function () { + Tea.action("/servers/server/settings/origins/delete?" + that.vParams + "&originId=" + originId + "&originType=" + originType) + .post() + .success(function () { + window.location.reload() + }) + }) + } + }, + template: `
+

主要源站 [添加主要源站]

+

暂时还没有优先源站。

+ + +

备用源站 [添加备用源站]

+

暂时还没有备用源站。

+ +
` +}) + +Vue.component("origin-list-table", { + props: ["v-origins", "v-origin-type"], + data: function () { + return {} + }, + methods: { + deleteOrigin: function (originId) { + this.$emit("deleteOrigin", originId, this.vOriginType) + }, + updateOrigin: function (originId) { + this.$emit("updateOrigin", originId, this.vOriginType) + } + }, + template: ` + + + + + + + + + + + + + +
源站地址权重操作
{{origin.addr}}{{origin.weight}} + 修改   + 删除 +
` +}) \ No newline at end of file diff --git a/web/public/js/components/server/origin-scheduling-view-box.js b/web/public/js/components/server/origin-scheduling-view-box.js new file mode 100644 index 00000000..cd65697e --- /dev/null +++ b/web/public/js/components/server/origin-scheduling-view-box.js @@ -0,0 +1,34 @@ +Vue.component("origin-scheduling-view-box", { + props: ["v-scheduling", "v-params"], + data: function () { + let scheduling = this.vScheduling + if (scheduling == null) { + scheduling = {} + } + return { + scheduling: scheduling + } + }, + methods: { + update: function () { + teaweb.popup("/servers/server/settings/reverseProxy/updateSchedulingPopup?" + this.vParams, { + height: "21em", + callback: function () { + window.location.reload() + }, + }) + } + }, + template: `
+
+ + + + + +
当前正在使用的算法 + {{scheduling.name}}   [修改] +

{{scheduling.description}}

+
+
` +}) \ No newline at end of file diff --git a/web/views/@default/servers/addOriginPopup.html b/web/views/@default/servers/addOriginPopup.html index 70461aac..a538fa69 100644 --- a/web/views/@default/servers/addOriginPopup.html +++ b/web/views/@default/servers/addOriginPopup.html @@ -8,7 +8,7 @@ 源站协议 - diff --git a/web/views/@default/servers/create.html b/web/views/@default/servers/create.html index 5fd4a311..943c4aef 100644 --- a/web/views/@default/servers/create.html +++ b/web/views/@default/servers/create.html @@ -51,7 +51,7 @@ - + 绑定域名 diff --git a/web/views/@default/servers/server/settings/origins/addPopup.html b/web/views/@default/servers/server/settings/origins/addPopup.html new file mode 100644 index 00000000..b7991442 --- /dev/null +++ b/web/views/@default/servers/server/settings/origins/addPopup.html @@ -0,0 +1,34 @@ +{$layout "layout_popup"} + +

添加源站地址

+ +
+ + + + + + + + + + + +
源站协议 + + + + + +
源站地址 + +

源站服务器地址,通常是一个IP(或域名)加端口,不需要加 http:// 或 https://

+
+ +
\ No newline at end of file diff --git a/web/views/@default/servers/server/settings/origins/addPopup.js b/web/views/@default/servers/server/settings/origins/addPopup.js new file mode 100644 index 00000000..b0f74795 --- /dev/null +++ b/web/views/@default/servers/server/settings/origins/addPopup.js @@ -0,0 +1,3 @@ +Tea.context(function () { + this.success = NotifyPopup; +}); \ No newline at end of file diff --git a/web/views/@default/servers/server/settings/origins/updatePopup.html b/web/views/@default/servers/server/settings/origins/updatePopup.html new file mode 100644 index 00000000..763f7d69 --- /dev/null +++ b/web/views/@default/servers/server/settings/origins/updatePopup.html @@ -0,0 +1,36 @@ +{$layout "layout_popup"} + +

添加源站地址

+ +
+ + + + + + + + + + + + + +
源站协议 + + + + + +
源站地址 + +

源站服务器地址,通常是一个IP(或域名)加端口,不需要加 http:// 或 https://

+
+ +
\ No newline at end of file diff --git a/web/views/@default/servers/server/settings/origins/updatePopup.js b/web/views/@default/servers/server/settings/origins/updatePopup.js new file mode 100644 index 00000000..b0f74795 --- /dev/null +++ b/web/views/@default/servers/server/settings/origins/updatePopup.js @@ -0,0 +1,3 @@ +Tea.context(function () { + this.success = NotifyPopup; +}); \ No newline at end of file diff --git a/web/views/@default/servers/server/settings/reverseProxy/@menu.html b/web/views/@default/servers/server/settings/reverseProxy/@menu.html new file mode 100644 index 00000000..5f2fab40 --- /dev/null +++ b/web/views/@default/servers/server/settings/reverseProxy/@menu.html @@ -0,0 +1,4 @@ + + 源站列表 + 调度算法 + \ No newline at end of file diff --git a/web/views/@default/servers/server/settings/reverseProxy/index.html b/web/views/@default/servers/server/settings/reverseProxy/index.html index eae519e9..fce39a1c 100644 --- a/web/views/@default/servers/server/settings/reverseProxy/index.html +++ b/web/views/@default/servers/server/settings/reverseProxy/index.html @@ -1,7 +1,8 @@ {$layout} - {$template "/left_menu"}
-

此功能暂未开放,敬请期待。

+ {$template "menu"} + +
\ No newline at end of file diff --git a/web/views/@default/servers/server/settings/reverseProxy/scheduling.html b/web/views/@default/servers/server/settings/reverseProxy/scheduling.html new file mode 100644 index 00000000..312aef81 --- /dev/null +++ b/web/views/@default/servers/server/settings/reverseProxy/scheduling.html @@ -0,0 +1,8 @@ +{$layout} +{$template "/left_menu"} + +
+ {$template "menu"} + + +
\ No newline at end of file diff --git a/web/views/@default/servers/server/settings/reverseProxy/updateSchedulingPopup.html b/web/views/@default/servers/server/settings/reverseProxy/updateSchedulingPopup.html new file mode 100644 index 00000000..d6707748 --- /dev/null +++ b/web/views/@default/servers/server/settings/reverseProxy/updateSchedulingPopup.html @@ -0,0 +1,60 @@ +{$layout "layout_popup"} + +

修改调度算法

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
选择调度算法 + +

{{schedulingTypeDescription}}

+
+ Key + + +

用来计算Hash的字符串,其中可以使用变量。

+
常用变量 + +
参数类型 + +
参数名 + +

记录或指定后端服务器的参数名,只能是英文字母和数字的组合,不允许有下划线(因为在HTTP Header中下划线是不标准的)

+
+ +
\ No newline at end of file diff --git a/web/views/@default/servers/server/settings/reverseProxy/updateSchedulingPopup.js b/web/views/@default/servers/server/settings/reverseProxy/updateSchedulingPopup.js new file mode 100644 index 00000000..b7e8bce3 --- /dev/null +++ b/web/views/@default/servers/server/settings/reverseProxy/updateSchedulingPopup.js @@ -0,0 +1,39 @@ +Tea.context(function () { + var that = this; + + this.success = NotifyPopup + + this.selectedType = this.scheduling.code; + this.schedulingTypeDescription = null; + + this.changeSchedulingType = function () { + this.schedulingTypeDescription = this.schedulingTypes.$find(function (k, v) { + return v.code == that.selectedType; + }).description; + }; + this.changeSchedulingType(); + + // hash + this.hashKey = ""; + this.hashVar = ""; + if (this.scheduling.code == "hash") { + this.hashKey = this.scheduling.options.key; + } else { + this.hashKey = "${remoteAddr}"; + } + + this.changeHashVar = function () { + if (this.hashVar.length > 0) { + this.hashKey = this.hashVar; + } + }; + + // sticky + if (this.scheduling.code == "sticky") { + this.stickyType = this.scheduling.options.type; + this.stickyParam = this.scheduling.options.param; + } else { + this.stickyType = "cookie"; + this.stickyParam = "Origin"; + } +}); \ No newline at end of file