Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2c42ca2b7 | ||
|
|
2a6db6ebfe | ||
|
|
30d8edbdcf | ||
|
|
177afafe12 | ||
|
|
98765b6e2a | ||
|
|
e4e0aab010 | ||
|
|
ed87b4e2a9 | ||
|
|
337eb36d25 | ||
|
|
c44e40d72d | ||
|
|
2e8ba831a1 | ||
|
|
a706c2a5a5 | ||
|
|
093826222a | ||
|
|
0d7b487afc | ||
|
|
8de17b6d9c | ||
|
|
49d217a883 | ||
|
|
4827555899 |
@@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/installers/helpers"
|
||||||
"github.com/iwind/gosock/pkg/gosock"
|
"github.com/iwind/gosock/pkg/gosock"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -51,7 +51,7 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
unzip := utils.NewUnzip(zipPath, targetPath)
|
unzip := helpers.NewUnzip(zipPath, targetPath)
|
||||||
err := unzip.Run()
|
err := unzip.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stderr("ERROR: " + err.Error())
|
stderr("ERROR: " + err.Error())
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
// 注意这里的依赖文件应该最小化,从而使编译后的文件最小化
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/installers/helpers"
|
||||||
"github.com/iwind/gosock/pkg/gosock"
|
"github.com/iwind/gosock/pkg/gosock"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -51,7 +52,7 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
unzip := utils.NewUnzip(zipPath, targetPath)
|
unzip := helpers.NewUnzip(zipPath, targetPath)
|
||||||
err := unzip.Run()
|
err := unzip.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stderr("ERROR: " + err.Error())
|
stderr("ERROR: " + err.Error())
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package teaconst
|
package teaconst
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "0.5.3"
|
Version = "0.5.5"
|
||||||
|
|
||||||
ProductName = "Edge API"
|
ProductName = "Edge API"
|
||||||
ProcessName = "edge-api"
|
ProcessName = "edge-api"
|
||||||
@@ -18,9 +18,9 @@ const (
|
|||||||
|
|
||||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||||
|
|
||||||
NodeVersion = "0.5.3"
|
NodeVersion = "0.5.5"
|
||||||
UserNodeVersion = "0.5.0"
|
UserNodeVersion = "0.5.5"
|
||||||
DNSNodeVersion = "0.2.7"
|
DNSNodeVersion = "0.2.8"
|
||||||
AuthorityNodeVersion = "0.0.2"
|
AuthorityNodeVersion = "0.0.2"
|
||||||
MonitorNodeVersion = "0.0.4"
|
MonitorNodeVersion = "0.0.4"
|
||||||
ReportNodeVersion = "0.1.1"
|
ReportNodeVersion = "0.1.1"
|
||||||
|
|||||||
@@ -13,22 +13,26 @@ type OrderMethod struct {
|
|||||||
Url string `field:"url"` // URL
|
Url string `field:"url"` // URL
|
||||||
Secret string `field:"secret"` // 密钥
|
Secret string `field:"secret"` // 密钥
|
||||||
Params dbs.JSON `field:"params"` // 参数
|
Params dbs.JSON `field:"params"` // 参数
|
||||||
|
ClientType string `field:"clientType"` // 客户端类型
|
||||||
|
QrcodeTitle string `field:"qrcodeTitle"` // 二维码标题
|
||||||
Order uint32 `field:"order"` // 排序
|
Order uint32 `field:"order"` // 排序
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderMethodOperator struct {
|
type OrderMethodOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
Name interface{} // 名称
|
Name any // 名称
|
||||||
IsOn interface{} // 是否启用
|
IsOn any // 是否启用
|
||||||
Description interface{} // 描述
|
Description any // 描述
|
||||||
ParentCode interface{} // 内置的父级代号
|
ParentCode any // 内置的父级代号
|
||||||
Code interface{} // 代号
|
Code any // 代号
|
||||||
Url interface{} // URL
|
Url any // URL
|
||||||
Secret interface{} // 密钥
|
Secret any // 密钥
|
||||||
Params interface{} // 参数
|
Params any // 参数
|
||||||
Order interface{} // 排序
|
ClientType any // 客户端类型
|
||||||
State interface{} // 状态
|
QrcodeTitle any // 二维码标题
|
||||||
|
Order any // 排序
|
||||||
|
State any // 状态
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOrderMethodOperator() *OrderMethodOperator {
|
func NewOrderMethodOperator() *OrderMethodOperator {
|
||||||
|
|||||||
@@ -976,7 +976,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, server := range servers {
|
for _, server := range servers {
|
||||||
serverConfig, err := SharedServerDAO.ComposeServerConfig(tx, server, cacheMap, true)
|
serverConfig, err := SharedServerDAO.ComposeServerConfig(tx, server, cacheMap, true, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package models
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -29,47 +28,3 @@ func (this *NSCluster) HasDDoSProtection() bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeHosts 解析主机地址
|
|
||||||
func (this *NSCluster) DecodeHosts() []string {
|
|
||||||
if IsNull(this.Hosts) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var hosts = []string{}
|
|
||||||
err := json.Unmarshal(this.Hosts, &hosts)
|
|
||||||
if err != nil {
|
|
||||||
remotelogs.Error("NSCluster.DecodeHosts", "decode failed: "+err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return hosts
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeSOAConfig 解析SOA设置
|
|
||||||
func (this *NSCluster) DecodeSOAConfig() *dnsconfigs.NSSOAConfig {
|
|
||||||
var config = dnsconfigs.DefaultNSSOAConfig()
|
|
||||||
if IsNull(this.Soa) {
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
err := json.Unmarshal(this.Soa, config)
|
|
||||||
if err != nil {
|
|
||||||
remotelogs.Error("NSCluster.DecodeSOAConfig", "decode failed: "+err.Error())
|
|
||||||
}
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeAnswerConfig 解析应答设置
|
|
||||||
func (this *NSCluster) DecodeAnswerConfig() *dnsconfigs.NSAnswerConfig {
|
|
||||||
var config = dnsconfigs.DefaultNSAnswerConfig()
|
|
||||||
|
|
||||||
if IsNull(this.Answer) {
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
err := json.Unmarshal(this.Answer, config)
|
|
||||||
if err != nil {
|
|
||||||
remotelogs.Error("NSCluster.DecodeAnswerConfig", "decode failed: "+err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1009,12 +1009,12 @@ func (this *ServerDAO) ComposeServerConfigWithServerId(tx *dbs.Tx, serverId int6
|
|||||||
if server == nil {
|
if server == nil {
|
||||||
return nil, ErrNotFound
|
return nil, ErrNotFound
|
||||||
}
|
}
|
||||||
return this.ComposeServerConfig(tx, server, nil, forNode)
|
return this.ComposeServerConfig(tx, server, nil, forNode, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComposeServerConfig 构造服务的Config
|
// ComposeServerConfig 构造服务的Config
|
||||||
// forNode 是否是节点请求
|
// forNode 是否是节点请求
|
||||||
func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap *utils.CacheMap, forNode bool) (*serverconfigs.ServerConfig, error) {
|
func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap *utils.CacheMap, forNode bool, forList bool) (*serverconfigs.ServerConfig, error) {
|
||||||
if server == nil {
|
if server == nil {
|
||||||
return nil, ErrNotFound
|
return nil, ErrNotFound
|
||||||
}
|
}
|
||||||
@@ -1039,7 +1039,7 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
|
|||||||
|
|
||||||
var groupConfig *serverconfigs.ServerGroupConfig
|
var groupConfig *serverconfigs.ServerGroupConfig
|
||||||
for _, groupId := range server.DecodeGroupIds() {
|
for _, groupId := range server.DecodeGroupIds() {
|
||||||
groupConfig1, err := SharedServerGroupDAO.ComposeGroupConfig(tx, groupId, cacheMap)
|
groupConfig1, err := SharedServerGroupDAO.ComposeGroupConfig(tx, groupId, forList, cacheMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1062,28 +1062,30 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CNAME
|
// CNAME
|
||||||
config.SupportCNAME = server.SupportCNAME == 1
|
if !forList {
|
||||||
if server.ClusterId > 0 && len(server.DnsName) > 0 {
|
config.SupportCNAME = server.SupportCNAME == 1
|
||||||
clusterDNS, err := SharedNodeClusterDAO.FindClusterDNSInfo(tx, int64(server.ClusterId), cacheMap)
|
if server.ClusterId > 0 && len(server.DnsName) > 0 {
|
||||||
if err != nil {
|
clusterDNS, err := SharedNodeClusterDAO.FindClusterDNSInfo(tx, int64(server.ClusterId), cacheMap)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if clusterDNS != nil && clusterDNS.DnsDomainId > 0 {
|
|
||||||
clusterDNSConfig, err := clusterDNS.DecodeDNSConfig()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if clusterDNS != nil && clusterDNS.DnsDomainId > 0 {
|
||||||
|
clusterDNSConfig, err := clusterDNS.DecodeDNSConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
domain, err := dns.SharedDNSDomainDAO.FindEnabledDNSDomain(tx, int64(clusterDNS.DnsDomainId), cacheMap)
|
domain, err := dns.SharedDNSDomainDAO.FindEnabledDNSDomain(tx, int64(clusterDNS.DnsDomainId), cacheMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if domain != nil {
|
if domain != nil {
|
||||||
var cname = server.DnsName + "." + domain.Name
|
var cname = server.DnsName + "." + domain.Name
|
||||||
config.CNameDomain = cname
|
config.CNameDomain = cname
|
||||||
if clusterDNSConfig.CNAMEAsDomain {
|
if clusterDNSConfig.CNAMEAsDomain {
|
||||||
config.CNameAsDomain = true
|
config.CNameAsDomain = true
|
||||||
config.AliasServerNames = append(config.AliasServerNames, cname)
|
config.AliasServerNames = append(config.AliasServerNames, cname)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1174,61 +1176,71 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Web
|
// Web
|
||||||
if server.WebId > 0 {
|
if !forList {
|
||||||
webConfig, err := SharedHTTPWebDAO.ComposeWebConfig(tx, int64(server.WebId), cacheMap)
|
if server.WebId > 0 {
|
||||||
if err != nil {
|
webConfig, err := SharedHTTPWebDAO.ComposeWebConfig(tx, int64(server.WebId), cacheMap)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
if webConfig != nil {
|
}
|
||||||
config.Web = webConfig
|
if webConfig != nil {
|
||||||
|
config.Web = webConfig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReverseProxy
|
// ReverseProxy
|
||||||
if IsNotNull(server.ReverseProxy) {
|
if !forList {
|
||||||
var reverseProxyRef = &serverconfigs.ReverseProxyRef{}
|
if IsNotNull(server.ReverseProxy) {
|
||||||
err := json.Unmarshal(server.ReverseProxy, reverseProxyRef)
|
var reverseProxyRef = &serverconfigs.ReverseProxyRef{}
|
||||||
if err != nil {
|
err := json.Unmarshal(server.ReverseProxy, reverseProxyRef)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
config.ReverseProxyRef = reverseProxyRef
|
}
|
||||||
|
config.ReverseProxyRef = reverseProxyRef
|
||||||
|
|
||||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if reverseProxyConfig != nil {
|
if reverseProxyConfig != nil {
|
||||||
config.ReverseProxy = reverseProxyConfig
|
config.ReverseProxy = reverseProxyConfig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WAF策略
|
// WAF策略
|
||||||
var clusterId = int64(server.ClusterId)
|
var clusterId = int64(server.ClusterId)
|
||||||
httpFirewallPolicyId, err := SharedNodeClusterDAO.FindClusterHTTPFirewallPolicyId(tx, clusterId, cacheMap)
|
if !forList {
|
||||||
if err != nil {
|
httpFirewallPolicyId, err := SharedNodeClusterDAO.FindClusterHTTPFirewallPolicyId(tx, clusterId, cacheMap)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if httpFirewallPolicyId > 0 {
|
|
||||||
config.HTTPFirewallPolicyId = httpFirewallPolicyId
|
|
||||||
}
|
|
||||||
|
|
||||||
// 缓存策略
|
|
||||||
httpCachePolicyId, err := SharedNodeClusterDAO.FindClusterHTTPCachePolicyId(tx, clusterId, cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if httpCachePolicyId > 0 {
|
|
||||||
config.HTTPCachePolicyId = httpCachePolicyId
|
|
||||||
}
|
|
||||||
|
|
||||||
// traffic limit
|
|
||||||
if len(server.TrafficLimit) > 0 {
|
|
||||||
var trafficLimitConfig = &serverconfigs.TrafficLimitConfig{}
|
|
||||||
err = json.Unmarshal(server.TrafficLimit, trafficLimitConfig)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
config.TrafficLimit = trafficLimitConfig
|
if httpFirewallPolicyId > 0 {
|
||||||
|
config.HTTPFirewallPolicyId = httpFirewallPolicyId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缓存策略
|
||||||
|
if !forList {
|
||||||
|
httpCachePolicyId, err := SharedNodeClusterDAO.FindClusterHTTPCachePolicyId(tx, clusterId, cacheMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if httpCachePolicyId > 0 {
|
||||||
|
config.HTTPCachePolicyId = httpCachePolicyId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// traffic limit
|
||||||
|
if !forList {
|
||||||
|
if len(server.TrafficLimit) > 0 {
|
||||||
|
var trafficLimitConfig = &serverconfigs.TrafficLimitConfig{}
|
||||||
|
err := json.Unmarshal(server.TrafficLimit, trafficLimitConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.TrafficLimit = trafficLimitConfig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户套餐
|
// 用户套餐
|
||||||
@@ -1271,7 +1283,7 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
|
|||||||
if config.TrafficLimit != nil && config.TrafficLimit.IsOn && !config.TrafficLimit.IsEmpty() {
|
if config.TrafficLimit != nil && config.TrafficLimit.IsOn && !config.TrafficLimit.IsEmpty() {
|
||||||
if len(server.TrafficLimitStatus) > 0 {
|
if len(server.TrafficLimitStatus) > 0 {
|
||||||
var status = &serverconfigs.TrafficLimitStatus{}
|
var status = &serverconfigs.TrafficLimitStatus{}
|
||||||
err = json.Unmarshal(server.TrafficLimitStatus, status)
|
err := json.Unmarshal(server.TrafficLimitStatus, status)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1282,14 +1294,16 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UAM
|
// UAM
|
||||||
if teaconst.IsPlus && IsNotNull(server.Uam) {
|
if !forList {
|
||||||
var uamConfig = &serverconfigs.UAMConfig{}
|
if teaconst.IsPlus && IsNotNull(server.Uam) {
|
||||||
err = json.Unmarshal(server.Uam, uamConfig)
|
var uamConfig = &serverconfigs.UAMConfig{}
|
||||||
if err != nil {
|
err := json.Unmarshal(server.Uam, uamConfig)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
if uamConfig.IsOn {
|
}
|
||||||
config.UAM = uamConfig
|
if uamConfig.IsOn {
|
||||||
|
config.UAM = uamConfig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ func (this *ServerGroupDAO) InitGroupWeb(tx *dbs.Tx, groupId int64) (int64, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ComposeGroupConfig 组合配置
|
// ComposeGroupConfig 组合配置
|
||||||
func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, cacheMap *utils.CacheMap) (*serverconfigs.ServerGroupConfig, error) {
|
func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, forList bool, cacheMap *utils.CacheMap) (*serverconfigs.ServerGroupConfig, error) {
|
||||||
if cacheMap == nil {
|
if cacheMap == nil {
|
||||||
cacheMap = utils.NewCacheMap()
|
cacheMap = utils.NewCacheMap()
|
||||||
}
|
}
|
||||||
@@ -315,65 +315,67 @@ func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, cacheM
|
|||||||
IsOn: group.IsOn,
|
IsOn: group.IsOn,
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsNotNull(group.HttpReverseProxy) {
|
if !forList {
|
||||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
if IsNotNull(group.HttpReverseProxy) {
|
||||||
err := json.Unmarshal(group.HttpReverseProxy, reverseProxyRef)
|
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||||
if err != nil {
|
err := json.Unmarshal(group.HttpReverseProxy, reverseProxyRef)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
config.HTTPReverseProxyRef = reverseProxyRef
|
}
|
||||||
|
config.HTTPReverseProxyRef = reverseProxyRef
|
||||||
|
|
||||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
}
|
||||||
|
if reverseProxyConfig != nil {
|
||||||
|
config.HTTPReverseProxy = reverseProxyConfig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if reverseProxyConfig != nil {
|
|
||||||
config.HTTPReverseProxy = reverseProxyConfig
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if IsNotNull(group.TcpReverseProxy) {
|
if IsNotNull(group.TcpReverseProxy) {
|
||||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||||
err := json.Unmarshal(group.TcpReverseProxy, reverseProxyRef)
|
err := json.Unmarshal(group.TcpReverseProxy, reverseProxyRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
config.TCPReverseProxyRef = reverseProxyRef
|
config.TCPReverseProxyRef = reverseProxyRef
|
||||||
|
|
||||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
}
|
||||||
|
if reverseProxyConfig != nil {
|
||||||
|
config.TCPReverseProxy = reverseProxyConfig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if reverseProxyConfig != nil {
|
|
||||||
config.TCPReverseProxy = reverseProxyConfig
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if IsNotNull(group.UdpReverseProxy) {
|
if IsNotNull(group.UdpReverseProxy) {
|
||||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||||
err := json.Unmarshal(group.UdpReverseProxy, reverseProxyRef)
|
err := json.Unmarshal(group.UdpReverseProxy, reverseProxyRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
config.UDPReverseProxyRef = reverseProxyRef
|
config.UDPReverseProxyRef = reverseProxyRef
|
||||||
|
|
||||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
}
|
||||||
|
if reverseProxyConfig != nil {
|
||||||
|
config.UDPReverseProxy = reverseProxyConfig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if reverseProxyConfig != nil {
|
|
||||||
config.UDPReverseProxy = reverseProxyConfig
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// web
|
// web
|
||||||
if group.WebId > 0 {
|
if group.WebId > 0 {
|
||||||
webConfig, err := SharedHTTPWebDAO.ComposeWebConfig(tx, int64(group.WebId), cacheMap)
|
webConfig, err := SharedHTTPWebDAO.ComposeWebConfig(tx, int64(group.WebId), cacheMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if webConfig != nil {
|
if webConfig != nil {
|
||||||
config.Web = webConfig
|
config.Web = webConfig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ func (this *UserNodeDAO) CountAllEnabledUserNodesWithSSLPolicyIds(tx *dbs.Tx, ss
|
|||||||
if len(sslPolicyIds) == 0 {
|
if len(sslPolicyIds) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
policyStringIds := []string{}
|
var policyStringIds = []string{}
|
||||||
for _, policyId := range sslPolicyIds {
|
for _, policyId := range sslPolicyIds {
|
||||||
policyStringIds = append(policyStringIds, strconv.FormatInt(policyId, 10))
|
policyStringIds = append(policyStringIds, strconv.FormatInt(policyId, 10))
|
||||||
}
|
}
|
||||||
@@ -310,3 +310,21 @@ func (this *UserNodeDAO) CountAllEnabledUserNodesWithSSLPolicyIds(tx *dbs.Tx, ss
|
|||||||
Param("policyIds", strings.Join(policyStringIds, ",")).
|
Param("policyIds", strings.Join(policyStringIds, ",")).
|
||||||
Count()
|
Count()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindUserNodeAccessAddr 获取用户节点访问地址
|
||||||
|
func (this *UserNodeDAO) FindUserNodeAccessAddr(tx *dbs.Tx) (string, error) {
|
||||||
|
nodes, err := this.ListEnabledUserNodes(tx, 0, 100)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
for _, node := range nodes {
|
||||||
|
addrs, err := node.DecodeAccessAddrStrings()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(addrs) > 0 {
|
||||||
|
return addrs[0], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,21 +22,21 @@ type UserNode struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UserNodeOperator struct {
|
type UserNodeOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
IsOn interface{} // 是否启用
|
IsOn any // 是否启用
|
||||||
UniqueId interface{} // 唯一ID
|
UniqueId any // 唯一ID
|
||||||
Secret interface{} // 密钥
|
Secret any // 密钥
|
||||||
Name interface{} // 名称
|
Name any // 名称
|
||||||
Description interface{} // 描述
|
Description any // 描述
|
||||||
Http interface{} // 监听的HTTP配置
|
Http any // 监听的HTTP配置
|
||||||
Https interface{} // 监听的HTTPS配置
|
Https any // 监听的HTTPS配置
|
||||||
AccessAddrs interface{} // 外部访问地址
|
AccessAddrs any // 外部访问地址
|
||||||
Order interface{} // 排序
|
Order any // 排序
|
||||||
State interface{} // 状态
|
State any // 状态
|
||||||
CreatedAt interface{} // 创建时间
|
CreatedAt any // 创建时间
|
||||||
AdminId interface{} // 管理员ID
|
AdminId any // 管理员ID
|
||||||
Weight interface{} // 权重
|
Weight any // 权重
|
||||||
Status interface{} // 运行状态
|
Status any // 运行状态
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserNodeOperator() *UserNodeOperator {
|
func NewUserNodeOperator() *UserNodeOperator {
|
||||||
|
|||||||
21
internal/dnsclients/edgeapi/response_base.go
Normal file
21
internal/dnsclients/edgeapi/response_base.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package edgeapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BaseResponse struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *BaseResponse) IsValid() bool {
|
||||||
|
return this.Code == 200
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *BaseResponse) Error() error {
|
||||||
|
return errors.New("code: " + types.String(this.Code) + ", message: " + this.Message)
|
||||||
|
}
|
||||||
11
internal/dnsclients/edgeapi/response_create_ns_record.go
Normal file
11
internal/dnsclients/edgeapi/response_create_ns_record.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package edgeapi
|
||||||
|
|
||||||
|
type CreateNSRecordResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
|
||||||
|
Data struct {
|
||||||
|
NSRecordId int64 `json:"nsRecordId"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
14
internal/dnsclients/edgeapi/response_find_all_ns_routes.go
Normal file
14
internal/dnsclients/edgeapi/response_find_all_ns_routes.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package edgeapi
|
||||||
|
|
||||||
|
type FindAllNSRoutesResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
|
||||||
|
Data struct {
|
||||||
|
NSRoutes []struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
} `json:"nsRoutes"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package edgeapi
|
||||||
|
|
||||||
|
type FindDomainWithNameResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
|
||||||
|
Data struct {
|
||||||
|
NSDomain struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package edgeapi
|
||||||
|
|
||||||
|
type FindNSRecordWithNameAndTypeResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
|
||||||
|
Data struct {
|
||||||
|
NSRecord struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
TTL int32 `json:"ttl"`
|
||||||
|
NSRoutes []struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
} `json:"nsRoutes"`
|
||||||
|
} `json:"nsRecord"`
|
||||||
|
}
|
||||||
|
}
|
||||||
12
internal/dnsclients/edgeapi/response_get_api_access_token.go
Normal file
12
internal/dnsclients/edgeapi/response_get_api_access_token.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package edgeapi
|
||||||
|
|
||||||
|
type GetAPIAccessToken struct {
|
||||||
|
BaseResponse
|
||||||
|
|
||||||
|
Data struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
ExpiresAt int64 `json:"expiresAt"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
8
internal/dnsclients/edgeapi/response_interface.go
Normal file
8
internal/dnsclients/edgeapi/response_interface.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package edgeapi
|
||||||
|
|
||||||
|
type ResponseInterface interface {
|
||||||
|
IsValid() bool
|
||||||
|
Error() error
|
||||||
|
}
|
||||||
16
internal/dnsclients/edgeapi/response_list_ns_domains.go
Normal file
16
internal/dnsclients/edgeapi/response_list_ns_domains.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package edgeapi
|
||||||
|
|
||||||
|
type ListNSDomainsResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
|
||||||
|
Data struct {
|
||||||
|
NSDomains []struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
IsOn bool `json:"isOn"`
|
||||||
|
IsDeleted bool `json:"isDeleted"`
|
||||||
|
} `json:"nsDomains"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
21
internal/dnsclients/edgeapi/response_list_ns_records.go
Normal file
21
internal/dnsclients/edgeapi/response_list_ns_records.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package edgeapi
|
||||||
|
|
||||||
|
type ListNSRecordsResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
|
||||||
|
Data struct {
|
||||||
|
NSRecords []struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
TTL int32 `json:"ttl"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
NSRoutes []struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
} `json:"nsRoutes"`
|
||||||
|
} `json:"nsRecords"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
7
internal/dnsclients/edgeapi/response_success.go
Normal file
7
internal/dnsclients/edgeapi/response_success.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package edgeapi
|
||||||
|
|
||||||
|
type SuccessResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
}
|
||||||
7
internal/dnsclients/edgeapi/response_update_ns_record.go
Normal file
7
internal/dnsclients/edgeapi/response_update_ns_record.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package edgeapi
|
||||||
|
|
||||||
|
type UpdateNSRecordResponse struct {
|
||||||
|
BaseResponse
|
||||||
|
}
|
||||||
1
internal/installers/helpers/README.md
Normal file
1
internal/installers/helpers/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
远程安装依赖文件,单独放在一个目录防止安装包过大
|
||||||
91
internal/installers/helpers/unzip.go
Normal file
91
internal/installers/helpers/unzip.go
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
package helpers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/zip"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Unzip struct {
|
||||||
|
zipFile string
|
||||||
|
targetDir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUnzip(zipFile string, targetDir string) *Unzip {
|
||||||
|
return &Unzip{
|
||||||
|
zipFile: zipFile,
|
||||||
|
targetDir: targetDir,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Unzip) Run() error {
|
||||||
|
if len(this.zipFile) == 0 {
|
||||||
|
return errors.New("zip file should not be empty")
|
||||||
|
}
|
||||||
|
if len(this.targetDir) == 0 {
|
||||||
|
return errors.New("target dir should not be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
reader, err := zip.OpenReader(this.zipFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
_ = reader.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
for _, file := range reader.File {
|
||||||
|
info := file.FileInfo()
|
||||||
|
target := this.targetDir + "/" + file.Name
|
||||||
|
|
||||||
|
// 目录
|
||||||
|
if info.IsDir() {
|
||||||
|
stat, err := os.Stat(target)
|
||||||
|
if err != nil {
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
err = os.MkdirAll(target, info.Mode())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if !stat.IsDir() {
|
||||||
|
err = os.MkdirAll(target, info.Mode())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件
|
||||||
|
err := func(file *zip.File, target string) error {
|
||||||
|
fileReader, err := file.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = fileReader.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
fileWriter, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, file.FileInfo().Mode())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = fileWriter.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, err = io.Copy(fileWriter, fileReader)
|
||||||
|
return err
|
||||||
|
}(file, target)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
17
internal/installers/helpers/unzip_test.go
Normal file
17
internal/installers/helpers/unzip_test.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package helpers_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/installers/helpers"
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUnzip_Run(t *testing.T) {
|
||||||
|
var unzip = helpers.NewUnzip(Tea.Root+"/deploy/edge-node-v0.0.1.zip", Tea.Root+"/deploy/")
|
||||||
|
err := unzip.Run()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("OK")
|
||||||
|
}
|
||||||
@@ -147,7 +147,7 @@ func (this *BaseInstaller) LookupLatestInstaller(filePrefix string) (string, err
|
|||||||
|
|
||||||
// InstallHelper 上传安装助手
|
// InstallHelper 上传安装助手
|
||||||
func (this *BaseInstaller) InstallHelper(targetDir string, role nodeconfigs.NodeRole) (env *Env, err error) {
|
func (this *BaseInstaller) InstallHelper(targetDir string, role nodeconfigs.NodeRole) (env *Env, err error) {
|
||||||
uname, _, err := this.client.Exec("uname -a")
|
uname, _, err := this.client.Exec("/usr/bin/uname -a")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return env, err
|
return env, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ func (this *NodeQueue) StopNode(nodeId int64) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 我们先尝试Systemd停止
|
// 我们先尝试Systemd停止
|
||||||
_, _, _ = installer.client.Exec("systemctl stop edge-node")
|
_, _, _ = installer.client.Exec("/usr/bin/systemctl stop edge-node")
|
||||||
|
|
||||||
// 执行stop
|
// 执行stop
|
||||||
_, stderr, err := installer.client.Exec(exe + " stop")
|
_, stderr, err := installer.client.Exec(exe + " stop")
|
||||||
|
|||||||
@@ -130,14 +130,16 @@ func (this *APINode) Start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 数据库通知启动
|
// 数据库通知启动
|
||||||
|
this.setProgress("DATABASE", "正在建立数据库模型")
|
||||||
logs.Println("[API_NODE]notify ready ...")
|
logs.Println("[API_NODE]notify ready ...")
|
||||||
dbs.NotifyReady()
|
dbs.NotifyReady()
|
||||||
|
|
||||||
// 设置时区
|
// 设置时区
|
||||||
|
this.setProgress("TIMEZONE", "正在设置时区")
|
||||||
this.setupTimeZone()
|
this.setupTimeZone()
|
||||||
|
|
||||||
// 读取配置
|
// 读取配置
|
||||||
this.setProgress("DATABASE", "加载API配置")
|
this.setProgress("DATABASE", "正在加载API配置")
|
||||||
logs.Println("[API_NODE]reading api config ...")
|
logs.Println("[API_NODE]reading api config ...")
|
||||||
config, err := configs.SharedAPIConfig()
|
config, err := configs.SharedAPIConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -384,6 +386,19 @@ func (this *APINode) setupDB() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查是否为root用户
|
||||||
|
config, _ := db.Config()
|
||||||
|
if config == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
dsnConfig, err := mysql.ParseDSN(config.Dsn)
|
||||||
|
if err != nil || dsnConfig == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if dsnConfig.User != "root" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// 设置Innodb事务提交模式
|
// 设置Innodb事务提交模式
|
||||||
{
|
{
|
||||||
result, err := db.FindOne("SHOW VARIABLES WHERE variable_name='innodb_flush_log_at_trx_commit'")
|
result, err := db.FindOne("SHOW VARIABLES WHERE variable_name='innodb_flush_log_at_trx_commit'")
|
||||||
|
|||||||
@@ -367,11 +367,6 @@ func (this *APINode) registerServices(server *grpc.Server) {
|
|||||||
pb.RegisterServerBillServiceServer(server, instance)
|
pb.RegisterServerBillServiceServer(server, instance)
|
||||||
this.rest(instance)
|
this.rest(instance)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
var instance = this.serviceInstance(&services.UserNodeService{}).(*services.UserNodeService)
|
|
||||||
pb.RegisterUserNodeServiceServer(server, instance)
|
|
||||||
this.rest(instance)
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
var instance = this.serviceInstance(&services.LoginService{}).(*services.LoginService)
|
var instance = this.serviceInstance(&services.LoginService{}).(*services.LoginService)
|
||||||
pb.RegisterLoginServiceServer(server, instance)
|
pb.RegisterLoginServiceServer(server, instance)
|
||||||
|
|||||||
@@ -840,21 +840,38 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 配置
|
// 配置
|
||||||
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, nil, false)
|
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, nil, false, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
var countServerNames int32 = 0
|
||||||
|
for _, serverName := range config.ServerNames {
|
||||||
|
if len(serverName.SubNames) > 0 {
|
||||||
|
countServerNames += int32(len(serverName.SubNames))
|
||||||
|
} else {
|
||||||
|
countServerNames++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.IgnoreServerNames && len(config.ServerNames) > 0 {
|
||||||
|
config.ServerNames = config.ServerNames[:1]
|
||||||
|
}
|
||||||
configJSON, err := json.Marshal(config)
|
configJSON, err := json.Marshal(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 忽略信息
|
||||||
|
if req.IgnoreServerNames {
|
||||||
|
server.ServerNames = nil
|
||||||
|
}
|
||||||
|
|
||||||
result = append(result, &pb.Server{
|
result = append(result, &pb.Server{
|
||||||
Id: int64(server.Id),
|
Id: int64(server.Id),
|
||||||
IsOn: server.IsOn,
|
IsOn: server.IsOn,
|
||||||
Type: server.Type,
|
Type: server.Type,
|
||||||
Config: configJSON,
|
Config: configJSON,
|
||||||
Name: server.Name,
|
Name: server.Name,
|
||||||
|
CountServerNames: countServerNames,
|
||||||
Description: server.Description,
|
Description: server.Description,
|
||||||
HttpJSON: server.Http,
|
HttpJSON: server.Http,
|
||||||
HttpsJSON: server.Https,
|
HttpsJSON: server.Https,
|
||||||
@@ -986,7 +1003,7 @@ func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEn
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 配置
|
// 配置
|
||||||
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, nil, userId > 0)
|
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, nil, userId > 0, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -463,7 +463,7 @@ func (this *ServerGroupService) FindEnabledServerGroupConfigInfo(ctx context.Con
|
|||||||
result.HasUDPReverseProxy = ref.IsPrior
|
result.HasUDPReverseProxy = ref.IsPrior
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := models.SharedServerGroupDAO.ComposeGroupConfig(tx, int64(group.Id), nil)
|
config, err := models.SharedServerGroupDAO.ComposeGroupConfig(tx, int64(group.Id), false, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,304 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
|
||||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserNodeService struct {
|
|
||||||
BaseService
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateUserNode 创建用户节点
|
|
||||||
func (this *UserNodeService) CreateUserNode(ctx context.Context, req *pb.CreateUserNodeRequest) (*pb.CreateUserNodeResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
nodeId, err := models.SharedUserNodeDAO.CreateUserNode(tx, req.Name, req.Description, req.HttpJSON, req.HttpsJSON, req.AccessAddrsJSON, req.IsOn)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.CreateUserNodeResponse{UserNodeId: nodeId}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateUserNode 修改用户节点
|
|
||||||
func (this *UserNodeService) UpdateUserNode(ctx context.Context, req *pb.UpdateUserNodeRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
err = models.SharedUserNodeDAO.UpdateUserNode(tx, req.UserNodeId, req.Name, req.Description, req.HttpJSON, req.HttpsJSON, req.AccessAddrsJSON, req.IsOn)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteUserNode 删除用户节点
|
|
||||||
func (this *UserNodeService) DeleteUserNode(ctx context.Context, req *pb.DeleteUserNodeRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
err = models.SharedUserNodeDAO.DisableUserNode(tx, req.UserNodeId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindAllEnabledUserNodes 列出所有可用用户节点
|
|
||||||
func (this *UserNodeService) FindAllEnabledUserNodes(ctx context.Context, req *pb.FindAllEnabledUserNodesRequest) (*pb.FindAllEnabledUserNodesResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
nodes, err := models.SharedUserNodeDAO.FindAllEnabledUserNodes(tx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := []*pb.UserNode{}
|
|
||||||
for _, node := range nodes {
|
|
||||||
accessAddrs, err := node.DecodeAccessAddrStrings()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result = append(result, &pb.UserNode{
|
|
||||||
Id: int64(node.Id),
|
|
||||||
IsOn: node.IsOn,
|
|
||||||
UniqueId: node.UniqueId,
|
|
||||||
Secret: node.Secret,
|
|
||||||
Name: node.Name,
|
|
||||||
Description: node.Description,
|
|
||||||
HttpJSON: node.Http,
|
|
||||||
HttpsJSON: node.Https,
|
|
||||||
AccessAddrsJSON: node.AccessAddrs,
|
|
||||||
AccessAddrs: accessAddrs,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.FindAllEnabledUserNodesResponse{UserNodes: result}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountAllEnabledUserNodes 计算用户节点数量
|
|
||||||
func (this *UserNodeService) CountAllEnabledUserNodes(ctx context.Context, req *pb.CountAllEnabledUserNodesRequest) (*pb.RPCCountResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
count, err := models.SharedUserNodeDAO.CountAllEnabledUserNodes(tx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.SuccessCount(count)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListEnabledUserNodes 列出单页的用户节点
|
|
||||||
func (this *UserNodeService) ListEnabledUserNodes(ctx context.Context, req *pb.ListEnabledUserNodesRequest) (*pb.ListEnabledUserNodesResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
nodes, err := models.SharedUserNodeDAO.ListEnabledUserNodes(tx, req.Offset, req.Size)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := []*pb.UserNode{}
|
|
||||||
for _, node := range nodes {
|
|
||||||
accessAddrs, err := node.DecodeAccessAddrStrings()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result = append(result, &pb.UserNode{
|
|
||||||
Id: int64(node.Id),
|
|
||||||
IsOn: node.IsOn,
|
|
||||||
UniqueId: node.UniqueId,
|
|
||||||
Secret: node.Secret,
|
|
||||||
Name: node.Name,
|
|
||||||
Description: node.Description,
|
|
||||||
HttpJSON: node.Http,
|
|
||||||
HttpsJSON: node.Https,
|
|
||||||
AccessAddrsJSON: node.AccessAddrs,
|
|
||||||
AccessAddrs: accessAddrs,
|
|
||||||
StatusJSON: node.Status,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.ListEnabledUserNodesResponse{UserNodes: result}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindEnabledUserNode 根据ID查找节点
|
|
||||||
func (this *UserNodeService) FindEnabledUserNode(ctx context.Context, req *pb.FindEnabledUserNodeRequest) (*pb.FindEnabledUserNodeResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
node, err := models.SharedUserNodeDAO.FindEnabledUserNode(tx, req.UserNodeId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if node == nil {
|
|
||||||
return &pb.FindEnabledUserNodeResponse{UserNode: nil}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
accessAddrs, err := node.DecodeAccessAddrStrings()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := &pb.UserNode{
|
|
||||||
Id: int64(node.Id),
|
|
||||||
IsOn: node.IsOn,
|
|
||||||
UniqueId: node.UniqueId,
|
|
||||||
Secret: node.Secret,
|
|
||||||
Name: node.Name,
|
|
||||||
Description: node.Description,
|
|
||||||
HttpJSON: node.Http,
|
|
||||||
HttpsJSON: node.Https,
|
|
||||||
AccessAddrsJSON: node.AccessAddrs,
|
|
||||||
AccessAddrs: accessAddrs,
|
|
||||||
}
|
|
||||||
return &pb.FindEnabledUserNodeResponse{UserNode: result}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindCurrentUserNode 获取当前用户节点的版本
|
|
||||||
func (this *UserNodeService) FindCurrentUserNode(ctx context.Context, req *pb.FindCurrentUserNodeRequest) (*pb.FindCurrentUserNodeResponse, error) {
|
|
||||||
_, err := this.ValidateUserNode(ctx, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
md, ok := metadata.FromIncomingContext(ctx)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("context: need 'nodeId'")
|
|
||||||
}
|
|
||||||
nodeIds := md.Get("nodeid")
|
|
||||||
if len(nodeIds) == 0 {
|
|
||||||
return nil, errors.New("invalid 'nodeId'")
|
|
||||||
}
|
|
||||||
nodeId := nodeIds[0]
|
|
||||||
node, err := models.SharedUserNodeDAO.FindEnabledUserNodeWithUniqueId(tx, nodeId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if node == nil {
|
|
||||||
return &pb.FindCurrentUserNodeResponse{UserNode: nil}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
accessAddrs, err := node.DecodeAccessAddrStrings()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := &pb.UserNode{
|
|
||||||
Id: int64(node.Id),
|
|
||||||
IsOn: node.IsOn,
|
|
||||||
UniqueId: node.UniqueId,
|
|
||||||
Secret: node.Secret,
|
|
||||||
Name: node.Name,
|
|
||||||
Description: node.Description,
|
|
||||||
HttpJSON: node.Http,
|
|
||||||
HttpsJSON: node.Https,
|
|
||||||
AccessAddrsJSON: node.AccessAddrs,
|
|
||||||
AccessAddrs: accessAddrs,
|
|
||||||
}
|
|
||||||
return &pb.FindCurrentUserNodeResponse{UserNode: result}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateUserNodeStatus 更新节点状态
|
|
||||||
func (this *UserNodeService) UpdateUserNodeStatus(ctx context.Context, req *pb.UpdateUserNodeStatusRequest) (*pb.RPCSuccess, error) {
|
|
||||||
// 校验节点
|
|
||||||
_, nodeId, err := this.ValidateNodeId(ctx, rpcutils.UserTypeUser)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.UserNodeId > 0 {
|
|
||||||
nodeId = req.UserNodeId
|
|
||||||
}
|
|
||||||
|
|
||||||
if nodeId <= 0 {
|
|
||||||
return nil, errors.New("'nodeId' should be greater than 0")
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
// 修改时间戳
|
|
||||||
var nodeStatus = &nodeconfigs.NodeStatus{}
|
|
||||||
err = json.Unmarshal(req.StatusJSON, nodeStatus)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("decode node status json failed: " + err.Error())
|
|
||||||
}
|
|
||||||
nodeStatus.UpdatedAt = time.Now().Unix()
|
|
||||||
|
|
||||||
// 保存
|
|
||||||
err = models.SharedUserNodeDAO.UpdateNodeStatus(tx, nodeId, nodeStatus)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountAllEnabledUserNodesWithSSLCertId 计算使用某个SSL证书的用户节点数量
|
|
||||||
func (this *UserNodeService) CountAllEnabledUserNodesWithSSLCertId(ctx context.Context, req *pb.CountAllEnabledUserNodesWithSSLCertIdRequest) (*pb.RPCCountResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
policyIds, err := models.SharedSSLPolicyDAO.FindAllEnabledPolicyIdsWithCertId(tx, req.SslCertId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(policyIds) == 0 {
|
|
||||||
return this.SuccessCount(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
count, err := models.SharedUserNodeDAO.CountAllEnabledUserNodesWithSSLPolicyIds(tx, policyIds)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return this.SuccessCount(count)
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -3,6 +3,7 @@ package setup
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/lists"
|
"github.com/iwind/TeaGo/lists"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
@@ -137,12 +138,22 @@ func (this *SQLDump) Dump(db *dbs.DB) (result *SQLDumpResult, err error) {
|
|||||||
func (this *SQLDump) Apply(db *dbs.DB, newResult *SQLDumpResult, showLog bool) (ops []string, err error) {
|
func (this *SQLDump) Apply(db *dbs.DB, newResult *SQLDumpResult, showLog bool) (ops []string, err error) {
|
||||||
// 设置Innodb事务提交模式
|
// 设置Innodb事务提交模式
|
||||||
{
|
{
|
||||||
|
// 检查是否为root用户
|
||||||
result, err := db.FindOne("SHOW VARIABLES WHERE variable_name='innodb_flush_log_at_trx_commit'")
|
config, _ := db.Config()
|
||||||
if err == nil && result != nil {
|
if config == nil {
|
||||||
var oldValue = result.GetInt("Value")
|
return nil, nil
|
||||||
if oldValue == 1 {
|
}
|
||||||
_, _ = db.Exec("SET GLOBAL innodb_flush_log_at_trx_commit=2")
|
dsnConfig, err := mysql.ParseDSN(config.Dsn)
|
||||||
|
if err != nil || dsnConfig == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if dsnConfig.User == "root" {
|
||||||
|
result, err := db.FindOne("SHOW VARIABLES WHERE variable_name='innodb_flush_log_at_trx_commit'")
|
||||||
|
if err == nil && result != nil {
|
||||||
|
var oldValue = result.GetInt("Value")
|
||||||
|
if oldValue == 1 {
|
||||||
|
_, _ = db.Exec("SET GLOBAL innodb_flush_log_at_trx_commit=2")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ func TestSQLDump_Apply(t *testing.T) {
|
|||||||
|
|
||||||
db2, err := dbs.NewInstanceFromConfig(&dbs.DBConfig{
|
db2, err := dbs.NewInstanceFromConfig(&dbs.DBConfig{
|
||||||
Driver: "mysql",
|
Driver: "mysql",
|
||||||
Dsn: "root:123456@tcp(192.168.2.60:3306)/db_edge_new?charset=utf8mb4&timeout=30s",
|
Dsn: "edge:123456@tcp(192.168.2.60:3306)/db_edge_new?charset=utf8mb4&timeout=30s",
|
||||||
Prefix: "edge",
|
Prefix: "edge",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -111,7 +111,8 @@ func (this *ServiceManager) installSystemdService(systemd, exePath string, args
|
|||||||
shortName := teaconst.SystemdServiceName
|
shortName := teaconst.SystemdServiceName
|
||||||
longName := "GoEdge API" // TODO 将来可以修改
|
longName := "GoEdge API" // TODO 将来可以修改
|
||||||
|
|
||||||
desc := `# Provides: ` + shortName + `
|
desc := `### BEGIN INIT INFO
|
||||||
|
# Provides: ` + shortName + `
|
||||||
# Required-Start: $all
|
# Required-Start: $all
|
||||||
# Required-Stop:
|
# Required-Stop:
|
||||||
# Default-Start: 2 3 4 5
|
# Default-Start: 2 3 4 5
|
||||||
|
|||||||
Reference in New Issue
Block a user