换成单集群模式
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
@@ -35,12 +37,17 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
func (this *HTTPDNSAppDAO) CreateApp(tx *dbs.Tx, name string, appId string, primaryClusterId int64, backupClusterId int64, isOn bool, userId int64) (int64, error) {
|
||||
func (this *HTTPDNSAppDAO) CreateApp(tx *dbs.Tx, name string, appId string, clusterIdsJSON []byte, isOn bool, userId int64) (int64, error) {
|
||||
var op = NewHTTPDNSAppOperator()
|
||||
op.Name = name
|
||||
op.AppId = appId
|
||||
op.PrimaryClusterId = primaryClusterId
|
||||
op.BackupClusterId = backupClusterId
|
||||
|
||||
if len(clusterIdsJSON) > 0 {
|
||||
op.ClusterIdsJSON = string(clusterIdsJSON)
|
||||
} else {
|
||||
op.ClusterIdsJSON = "[]"
|
||||
}
|
||||
|
||||
op.IsOn = isOn
|
||||
op.UserId = userId
|
||||
op.SNIMode = HTTPDNSSNIModeFixedHide
|
||||
@@ -54,18 +61,37 @@ func (this *HTTPDNSAppDAO) CreateApp(tx *dbs.Tx, name string, appId string, prim
|
||||
return types.Int64(op.Id), nil
|
||||
}
|
||||
|
||||
func (this *HTTPDNSAppDAO) UpdateApp(tx *dbs.Tx, appDbId int64, name string, primaryClusterId int64, backupClusterId int64, isOn bool, userId int64) error {
|
||||
func (this *HTTPDNSAppDAO) UpdateApp(tx *dbs.Tx, appDbId int64, name string, clusterIdsJSON []byte, isOn bool, userId int64) error {
|
||||
var op = NewHTTPDNSAppOperator()
|
||||
op.Id = appDbId
|
||||
op.Name = name
|
||||
op.PrimaryClusterId = primaryClusterId
|
||||
op.BackupClusterId = backupClusterId
|
||||
|
||||
if len(clusterIdsJSON) > 0 {
|
||||
op.ClusterIdsJSON = string(clusterIdsJSON)
|
||||
} else {
|
||||
op.ClusterIdsJSON = "[]"
|
||||
}
|
||||
|
||||
op.IsOn = isOn
|
||||
op.UserId = userId
|
||||
op.UpdatedAt = time.Now().Unix()
|
||||
return this.Save(tx, op)
|
||||
}
|
||||
|
||||
// ReadAppClusterIds reads cluster IDs from ClusterIdsJSON.
|
||||
func (this *HTTPDNSAppDAO) ReadAppClusterIds(app *HTTPDNSApp) []int64 {
|
||||
if app == nil {
|
||||
return nil
|
||||
}
|
||||
if len(app.ClusterIdsJSON) > 0 {
|
||||
var ids []int64
|
||||
if err := json.Unmarshal([]byte(app.ClusterIdsJSON), &ids); err == nil && len(ids) > 0 {
|
||||
return ids
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *HTTPDNSAppDAO) DisableApp(tx *dbs.Tx, appDbId int64) error {
|
||||
_, err := this.Query(tx).
|
||||
Pk(appDbId).
|
||||
|
||||
@@ -6,8 +6,7 @@ type HTTPDNSApp struct {
|
||||
Name string `field:"name"` // app name
|
||||
AppId string `field:"appId"` // external app id
|
||||
IsOn bool `field:"isOn"` // enabled
|
||||
PrimaryClusterId uint32 `field:"primaryClusterId"` // primary cluster id
|
||||
BackupClusterId uint32 `field:"backupClusterId"` // backup cluster id
|
||||
ClusterIdsJSON string `field:"clusterIdsJSON"` // cluster ids json
|
||||
SNIMode string `field:"sniMode"` // sni mode
|
||||
UserId int64 `field:"userId"` // owner user id
|
||||
CreatedAt uint64 `field:"createdAt"` // created unix ts
|
||||
@@ -21,8 +20,7 @@ type HTTPDNSAppOperator struct {
|
||||
Name any // app name
|
||||
AppId any // external app id
|
||||
IsOn any // enabled
|
||||
PrimaryClusterId any // primary cluster id
|
||||
BackupClusterId any // backup cluster id
|
||||
ClusterIdsJSON any // cluster ids json
|
||||
SNIMode any // sni mode
|
||||
UserId any // owner user id
|
||||
CreatedAt any // created unix ts
|
||||
|
||||
@@ -246,7 +246,7 @@ func (this *UserDAO) CreateUser(tx *dbs.Tx, username string,
|
||||
}
|
||||
|
||||
// UpdateUser 修改用户
|
||||
func (this *UserDAO) UpdateUser(tx *dbs.Tx, userId int64, username string, password string, fullname string, mobile string, tel string, email string, remark string, isOn bool, nodeClusterId int64, bandwidthAlgo systemconfigs.BandwidthAlgo) error {
|
||||
func (this *UserDAO) UpdateUser(tx *dbs.Tx, userId int64, username string, password string, fullname string, mobile string, tel string, email string, remark string, isOn bool, nodeClusterId int64, bandwidthAlgo systemconfigs.BandwidthAlgo, httpdnsClusterIdsJSON []byte) error {
|
||||
if userId <= 0 {
|
||||
return errors.New("invalid userId")
|
||||
}
|
||||
@@ -265,6 +265,11 @@ func (this *UserDAO) UpdateUser(tx *dbs.Tx, userId int64, username string, passw
|
||||
op.ClusterId = nodeClusterId
|
||||
op.BandwidthAlgo = bandwidthAlgo
|
||||
op.IsOn = isOn
|
||||
if len(httpdnsClusterIdsJSON) > 0 {
|
||||
op.HttpdnsClusterIds = string(httpdnsClusterIdsJSON)
|
||||
} else {
|
||||
op.HttpdnsClusterIds = "[]"
|
||||
}
|
||||
err := this.Save(tx, op)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -466,6 +471,21 @@ func (this *UserDAO) FindUserClusterId(tx *dbs.Tx, userId int64) (int64, error)
|
||||
FindInt64Col(0)
|
||||
}
|
||||
|
||||
// UpdateUserHttpdnsClusterIds 更新用户的HTTPDNS关联集群ID列表
|
||||
func (this *UserDAO) UpdateUserHttpdnsClusterIds(tx *dbs.Tx, userId int64, httpdnsClusterIdsJSON []byte) error {
|
||||
if userId <= 0 {
|
||||
return errors.New("invalid userId")
|
||||
}
|
||||
if len(httpdnsClusterIdsJSON) == 0 {
|
||||
httpdnsClusterIdsJSON = []byte("[]")
|
||||
}
|
||||
_, err := this.Query(tx).
|
||||
Pk(userId).
|
||||
Set("httpdnsClusterIds", httpdnsClusterIdsJSON).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateUserFeatures 更新单个用户Features
|
||||
func (this *UserDAO) UpdateUserFeatures(tx *dbs.Tx, userId int64, featuresJSON []byte) error {
|
||||
if userId <= 0 {
|
||||
|
||||
@@ -37,6 +37,7 @@ const (
|
||||
UserField_BandwidthAlgo dbs.FieldName = "bandwidthAlgo" // 带宽算法
|
||||
UserField_BandwidthModifier dbs.FieldName = "bandwidthModifier" // 带宽修正值
|
||||
UserField_Lang dbs.FieldName = "lang" // 语言代号
|
||||
UserField_HttpdnsClusterIds dbs.FieldName = "httpdnsClusterIds" // HTTPDNS关联集群ID列表
|
||||
)
|
||||
|
||||
// User 用户
|
||||
@@ -75,6 +76,7 @@ type User struct {
|
||||
BandwidthAlgo string `field:"bandwidthAlgo"` // 带宽算法
|
||||
BandwidthModifier float64 `field:"bandwidthModifier"` // 带宽修正值
|
||||
Lang string `field:"lang"` // 语言代号
|
||||
HttpdnsClusterIds dbs.JSON `field:"httpdnsClusterIds"` // HTTPDNS关联集群ID列表
|
||||
}
|
||||
|
||||
type UserOperator struct {
|
||||
@@ -112,6 +114,7 @@ type UserOperator struct {
|
||||
BandwidthAlgo any // 带宽算法
|
||||
BandwidthModifier any // 带宽修正值
|
||||
Lang any // 语言代号
|
||||
HttpdnsClusterIds any // HTTPDNS关联集群ID列表
|
||||
}
|
||||
|
||||
func NewUserOperator() *UserOperator {
|
||||
|
||||
@@ -33,11 +33,13 @@ const (
|
||||
fluentBitServiceName = "fluent-bit"
|
||||
fluentBitDefaultBinPath = "/opt/fluent-bit/bin/fluent-bit"
|
||||
fluentBitLocalPackagesRoot = "packages"
|
||||
fluentBitHTTPPathPattern = "/var/log/edge/edge-node/*.log"
|
||||
fluentBitDNSPathPattern = "/var/log/edge/edge-dns/*.log"
|
||||
fluentBitManagedMarker = "managed-by-edgeapi"
|
||||
fluentBitRoleNode = "node"
|
||||
fluentBitRoleDNS = "dns"
|
||||
fluentBitHTTPPathPattern = "/var/log/edge/edge-node/*.log"
|
||||
fluentBitDNSPathPattern = "/var/log/edge/edge-dns/*.log"
|
||||
fluentBitHTTPDNSPathPattern = "/var/log/edge/edge-httpdns/*.log"
|
||||
fluentBitManagedMarker = "managed-by-edgeapi"
|
||||
fluentBitRoleNode = "node"
|
||||
fluentBitRoleDNS = "dns"
|
||||
fluentBitRoleHTTPDNS = "httpdns"
|
||||
)
|
||||
|
||||
var errFluentBitLocalPackageNotFound = errors.New("fluent-bit local package not found")
|
||||
@@ -57,10 +59,11 @@ type fluentBitManagedMeta struct {
|
||||
}
|
||||
|
||||
type fluentBitDesiredConfig struct {
|
||||
Roles []string
|
||||
ClickHouse *systemconfigs.ClickHouseSetting
|
||||
HTTPPathPattern string
|
||||
DNSPathPattern string
|
||||
Roles []string
|
||||
ClickHouse *systemconfigs.ClickHouseSetting
|
||||
HTTPPathPattern string
|
||||
DNSPathPattern string
|
||||
HTTPDNSPathPattern string
|
||||
}
|
||||
|
||||
// SetupFluentBit 安装并托管 Fluent Bit 配置(离线包 + 平台渲染配置)。
|
||||
@@ -344,7 +347,7 @@ func mapNodeRole(role nodeconfigs.NodeRole) (string, error) {
|
||||
case nodeconfigs.NodeRoleDNS:
|
||||
return fluentBitRoleDNS, nil
|
||||
case nodeconfigs.NodeRoleHTTPDNS:
|
||||
return fluentBitRoleDNS, nil
|
||||
return fluentBitRoleHTTPDNS, nil
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported fluent-bit role '%s'", role)
|
||||
}
|
||||
@@ -354,7 +357,7 @@ func normalizeRoles(rawRoles []string) []string {
|
||||
roleSet := map[string]struct{}{}
|
||||
for _, role := range rawRoles {
|
||||
role = strings.ToLower(strings.TrimSpace(role))
|
||||
if role != fluentBitRoleNode && role != fluentBitRoleDNS {
|
||||
if role != fluentBitRoleNode && role != fluentBitRoleDNS && role != fluentBitRoleHTTPDNS {
|
||||
continue
|
||||
}
|
||||
roleSet[role] = struct{}{}
|
||||
@@ -420,6 +423,7 @@ func (this *BaseInstaller) buildDesiredFluentBitConfig(roles []string) (*fluentB
|
||||
|
||||
httpPathPattern := fluentBitHTTPPathPattern
|
||||
dnsPathPattern := fluentBitDNSPathPattern
|
||||
httpdnsPathPattern := fluentBitHTTPDNSPathPattern
|
||||
publicPolicyPath, err := this.readPublicAccessLogPolicyPath()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -429,13 +433,15 @@ func (this *BaseInstaller) buildDesiredFluentBitConfig(roles []string) (*fluentB
|
||||
pattern := strings.TrimRight(policyDir, "/") + "/*.log"
|
||||
httpPathPattern = pattern
|
||||
dnsPathPattern = pattern
|
||||
httpdnsPathPattern = pattern
|
||||
}
|
||||
|
||||
return &fluentBitDesiredConfig{
|
||||
Roles: normalizeRoles(roles),
|
||||
ClickHouse: ch,
|
||||
HTTPPathPattern: httpPathPattern,
|
||||
DNSPathPattern: dnsPathPattern,
|
||||
Roles: normalizeRoles(roles),
|
||||
ClickHouse: ch,
|
||||
HTTPPathPattern: httpPathPattern,
|
||||
DNSPathPattern: dnsPathPattern,
|
||||
HTTPDNSPathPattern: httpdnsPathPattern,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -556,6 +562,7 @@ func renderManagedConfig(desired *fluentBitDesiredConfig) (string, error) {
|
||||
|
||||
insertHTTP := url.QueryEscape(fmt.Sprintf("INSERT INTO %s.logs_ingest FORMAT JSONEachRow", desired.ClickHouse.Database))
|
||||
insertDNS := url.QueryEscape(fmt.Sprintf("INSERT INTO %s.dns_logs_ingest FORMAT JSONEachRow", desired.ClickHouse.Database))
|
||||
insertHTTPDNS := url.QueryEscape(fmt.Sprintf("INSERT INTO %s.httpdns_access_logs_ingest FORMAT JSONEachRow", desired.ClickHouse.Database))
|
||||
|
||||
lines := []string{
|
||||
"# " + fluentBitManagedMarker,
|
||||
@@ -604,6 +611,23 @@ func renderManagedConfig(desired *fluentBitDesiredConfig) (string, error) {
|
||||
)
|
||||
}
|
||||
|
||||
if hasRole(desired.Roles, fluentBitRoleHTTPDNS) {
|
||||
lines = append(lines,
|
||||
"[INPUT]",
|
||||
" Name tail",
|
||||
" Path "+desired.HTTPDNSPathPattern,
|
||||
" Tag app.httpdns.logs",
|
||||
" Parser json",
|
||||
" Refresh_Interval 2",
|
||||
" Read_from_Head false",
|
||||
" DB /var/lib/fluent-bit/httpdns-logs.db",
|
||||
" storage.type filesystem",
|
||||
" Mem_Buf_Limit 256MB",
|
||||
" Skip_Long_Lines On",
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
if hasRole(desired.Roles, fluentBitRoleNode) {
|
||||
lines = append(lines,
|
||||
"[OUTPUT]",
|
||||
@@ -666,6 +690,37 @@ func renderManagedConfig(desired *fluentBitDesiredConfig) (string, error) {
|
||||
lines = append(lines, "")
|
||||
}
|
||||
|
||||
if hasRole(desired.Roles, fluentBitRoleHTTPDNS) {
|
||||
lines = append(lines,
|
||||
"[OUTPUT]",
|
||||
" Name http",
|
||||
" Match app.httpdns.logs",
|
||||
" Host "+desired.ClickHouse.Host,
|
||||
" Port "+strconv.Itoa(desired.ClickHouse.Port),
|
||||
" URI /?query="+insertHTTPDNS,
|
||||
" Format json_lines",
|
||||
" http_user ${CH_USER}",
|
||||
" http_passwd ${CH_PASSWORD}",
|
||||
" json_date_key timestamp",
|
||||
" json_date_format epoch",
|
||||
" workers 2",
|
||||
" net.keepalive On",
|
||||
" Retry_Limit False",
|
||||
)
|
||||
if useTLS {
|
||||
lines = append(lines, " tls On")
|
||||
if desired.ClickHouse.TLSSkipVerify {
|
||||
lines = append(lines, " tls.verify Off")
|
||||
} else {
|
||||
lines = append(lines, " tls.verify On")
|
||||
}
|
||||
if strings.TrimSpace(desired.ClickHouse.TLSServerName) != "" {
|
||||
lines = append(lines, " tls.vhost "+strings.TrimSpace(desired.ClickHouse.TLSServerName))
|
||||
}
|
||||
}
|
||||
lines = append(lines, "")
|
||||
}
|
||||
|
||||
return strings.Join(lines, "\n"), nil
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,10 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/numberutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
var sharedHTTPDNSNodeQueue = NewHTTPDNSNodeQueue()
|
||||
@@ -98,9 +98,8 @@ func (q *HTTPDNSNodeQueue) InstallNode(nodeId int64, installStatus *models.NodeI
|
||||
return errors.New("can not find cluster")
|
||||
}
|
||||
|
||||
sshHost, sshPort, grantId, err := q.parseSSHInfo(node)
|
||||
sshHost, sshPort, grantId, err := q.parseSSHInfo(node, installStatus)
|
||||
if err != nil {
|
||||
installStatus.ErrorCode = "EMPTY_SSH"
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -287,35 +286,37 @@ func (q *HTTPDNSNodeQueue) resolveClusterTLSListenAddr(cluster *models.HTTPDNSCl
|
||||
return defaultListenAddr, nil
|
||||
}
|
||||
|
||||
func (q *HTTPDNSNodeQueue) parseSSHInfo(node *models.HTTPDNSNode) (string, int, int64, error) {
|
||||
func (q *HTTPDNSNodeQueue) parseSSHInfo(node *models.HTTPDNSNode, installStatus *models.NodeInstallStatus) (string, int, int64, error) {
|
||||
if node == nil {
|
||||
return "", 0, 0, errors.New("node should not be nil")
|
||||
}
|
||||
if len(node.InstallStatus) == 0 {
|
||||
return "", 0, 0, errors.New("ssh config should not be empty")
|
||||
}
|
||||
|
||||
statusMap := maps.Map{}
|
||||
err := json.Unmarshal(node.InstallStatus, &statusMap)
|
||||
login, err := models.SharedNodeLoginDAO.FindEnabledNodeLoginWithNodeId(nil, nodeconfigs.NodeRoleHTTPDNS, int64(node.Id))
|
||||
if err != nil {
|
||||
return "", 0, 0, errors.New("invalid install status data")
|
||||
return "", 0, 0, err
|
||||
}
|
||||
sshMap := statusMap.GetMap("ssh")
|
||||
if sshMap == nil {
|
||||
return "", 0, 0, errors.New("ssh config should not be empty")
|
||||
if login == nil {
|
||||
installStatus.ErrorCode = "EMPTY_SSH"
|
||||
return "", 0, 0, errors.New("ssh login not found for node '" + numberutils.FormatInt64(int64(node.Id)) + "'")
|
||||
}
|
||||
|
||||
host := sshMap.GetString("host")
|
||||
port := sshMap.GetInt("port")
|
||||
grantId := sshMap.GetInt64("grantId")
|
||||
if len(host) == 0 {
|
||||
sshParams, err := login.DecodeSSHParams()
|
||||
if err != nil {
|
||||
installStatus.ErrorCode = "EMPTY_SSH"
|
||||
return "", 0, 0, err
|
||||
}
|
||||
|
||||
if len(sshParams.Host) == 0 {
|
||||
installStatus.ErrorCode = "EMPTY_SSH_HOST"
|
||||
return "", 0, 0, errors.New("ssh host should not be empty")
|
||||
}
|
||||
if port <= 0 {
|
||||
port = 22
|
||||
if sshParams.Port <= 0 {
|
||||
sshParams.Port = 22
|
||||
}
|
||||
if grantId <= 0 {
|
||||
if sshParams.GrantId <= 0 {
|
||||
installStatus.ErrorCode = "EMPTY_GRANT"
|
||||
return "", 0, 0, errors.New("grant id should not be empty")
|
||||
}
|
||||
return host, port, grantId, nil
|
||||
|
||||
return sshParams.Host, sshParams.Port, sshParams.GrantId, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package httpdns
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
@@ -58,20 +60,23 @@ func toPBApp(app *models.HTTPDNSApp, secret *models.HTTPDNSAppSecret) *pb.HTTPDN
|
||||
signSecret = secret.SignSecret
|
||||
signUpdatedAt = int64(secret.SignUpdatedAt)
|
||||
}
|
||||
// 构建 clusterIdsJSON
|
||||
clusterIds := models.SharedHTTPDNSAppDAO.ReadAppClusterIds(app)
|
||||
clusterIdsJSON, _ := json.Marshal(clusterIds)
|
||||
|
||||
return &pb.HTTPDNSApp{
|
||||
Id: int64(app.Id),
|
||||
Name: app.Name,
|
||||
AppId: app.AppId,
|
||||
IsOn: app.IsOn,
|
||||
PrimaryClusterId: int64(app.PrimaryClusterId),
|
||||
BackupClusterId: int64(app.BackupClusterId),
|
||||
SniMode: app.SNIMode,
|
||||
SignEnabled: signEnabled,
|
||||
SignSecret: signSecret,
|
||||
SignUpdatedAt: signUpdatedAt,
|
||||
CreatedAt: int64(app.CreatedAt),
|
||||
UpdatedAt: int64(app.UpdatedAt),
|
||||
UserId: int64(app.UserId),
|
||||
Id: int64(app.Id),
|
||||
Name: app.Name,
|
||||
AppId: app.AppId,
|
||||
IsOn: app.IsOn,
|
||||
SniMode: app.SNIMode,
|
||||
SignEnabled: signEnabled,
|
||||
SignSecret: signSecret,
|
||||
SignUpdatedAt: signUpdatedAt,
|
||||
CreatedAt: int64(app.CreatedAt),
|
||||
UpdatedAt: int64(app.UpdatedAt),
|
||||
UserId: int64(app.UserId),
|
||||
ClusterIdsJSON: clusterIdsJSON,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,13 @@ package httpdns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -66,25 +67,35 @@ func (this *HTTPDNSAppService) CreateHTTPDNSApp(ctx context.Context, req *pb.Cre
|
||||
return errors.New("appId already exists")
|
||||
}
|
||||
|
||||
primaryClusterId := req.PrimaryClusterId
|
||||
backupClusterId := req.BackupClusterId
|
||||
if primaryClusterId <= 0 || backupClusterId <= 0 {
|
||||
defaultPrimaryClusterId, defaultBackupClusterId, err := readHTTPDNSDefaultClusterIds(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
// 使用 clusterIdsJSON;若为空则优先从用户关联集群获取,再 fallback 到全局默认
|
||||
clusterIdsJSON := req.ClusterIdsJSON
|
||||
if len(clusterIdsJSON) == 0 || string(clusterIdsJSON) == "[]" || string(clusterIdsJSON) == "null" {
|
||||
// 优先读取用户关联的 HTTPDNS 集群
|
||||
if req.UserId > 0 {
|
||||
user, userErr := models.SharedUserDAO.FindEnabledUser(tx, req.UserId, nil)
|
||||
if userErr != nil {
|
||||
return userErr
|
||||
}
|
||||
if user != nil && len(user.HttpdnsClusterIds) > 0 {
|
||||
var userClusterIds []int64
|
||||
if json.Unmarshal([]byte(user.HttpdnsClusterIds), &userClusterIds) == nil && len(userClusterIds) > 0 {
|
||||
clusterIdsJSON, _ = json.Marshal(userClusterIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
if primaryClusterId <= 0 {
|
||||
primaryClusterId = defaultPrimaryClusterId
|
||||
// fallback 到全局默认
|
||||
if len(clusterIdsJSON) == 0 || string(clusterIdsJSON) == "[]" || string(clusterIdsJSON) == "null" {
|
||||
defaultClusterIds, defaultErr := readHTTPDNSDefaultClusterIdList(tx)
|
||||
if defaultErr != nil {
|
||||
return defaultErr
|
||||
}
|
||||
if len(defaultClusterIds) > 0 {
|
||||
clusterIdsJSON, _ = json.Marshal(defaultClusterIds)
|
||||
}
|
||||
}
|
||||
if backupClusterId <= 0 {
|
||||
backupClusterId = defaultBackupClusterId
|
||||
}
|
||||
}
|
||||
if primaryClusterId > 0 && backupClusterId == primaryClusterId {
|
||||
backupClusterId = 0
|
||||
}
|
||||
|
||||
appDbId, err = models.SharedHTTPDNSAppDAO.CreateApp(tx, appName, appId, primaryClusterId, backupClusterId, req.IsOn, req.UserId)
|
||||
appDbId, err = models.SharedHTTPDNSAppDAO.CreateApp(tx, appName, appId, clusterIdsJSON, req.IsOn, req.UserId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -100,44 +111,47 @@ func (this *HTTPDNSAppService) CreateHTTPDNSApp(ctx context.Context, req *pb.Cre
|
||||
return &pb.CreateHTTPDNSAppResponse{AppDbId: appDbId}, nil
|
||||
}
|
||||
|
||||
func readHTTPDNSDefaultClusterIds(tx *dbs.Tx) (primaryClusterId int64, backupClusterId int64, err error) {
|
||||
primaryClusterId, err = models.SharedHTTPDNSClusterDAO.FindDefaultPrimaryClusterId(tx)
|
||||
// readHTTPDNSDefaultClusterIdList reads default cluster IDs from UserRegisterConfig.
|
||||
func readHTTPDNSDefaultClusterIdList(tx *dbs.Tx) ([]int64, error) {
|
||||
// 优先从 UserRegisterConfig 中读取
|
||||
configJSON, err := models.SharedSysSettingDAO.ReadSetting(tx, systemconfigs.SettingCodeUserRegisterConfig)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
backupClusterId = 0
|
||||
backupValueJSON, err := models.SharedSysSettingDAO.ReadSetting(tx, systemconfigs.SettingCodeHTTPDNSDefaultBackupClusterId)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
if len(backupValueJSON) > 0 {
|
||||
backupClusterId = types.Int64(string(backupValueJSON))
|
||||
}
|
||||
if backupClusterId > 0 {
|
||||
backupCluster, err := models.SharedHTTPDNSClusterDAO.FindEnabledCluster(tx, backupClusterId)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
if backupCluster == nil || !backupCluster.IsOn {
|
||||
backupClusterId = 0
|
||||
if len(configJSON) > 0 {
|
||||
var config userconfigs.UserRegisterConfig
|
||||
if err := json.Unmarshal(configJSON, &config); err == nil {
|
||||
if len(config.HTTPDNSDefaultClusterIds) > 0 {
|
||||
// 验证集群有效性
|
||||
var validIds []int64
|
||||
for _, id := range config.HTTPDNSDefaultClusterIds {
|
||||
if id <= 0 {
|
||||
continue
|
||||
}
|
||||
cluster, err := models.SharedHTTPDNSClusterDAO.FindEnabledCluster(tx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cluster != nil && cluster.IsOn {
|
||||
validIds = append(validIds, id)
|
||||
}
|
||||
}
|
||||
if len(validIds) > 0 {
|
||||
return validIds, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fallback:默认主集群
|
||||
primaryClusterId, err := models.SharedHTTPDNSClusterDAO.FindDefaultPrimaryClusterId(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if primaryClusterId > 0 {
|
||||
primaryCluster, err := models.SharedHTTPDNSClusterDAO.FindEnabledCluster(tx, primaryClusterId)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
if primaryCluster == nil || !primaryCluster.IsOn {
|
||||
primaryClusterId = 0
|
||||
}
|
||||
return []int64{primaryClusterId}, nil
|
||||
}
|
||||
|
||||
if primaryClusterId > 0 && backupClusterId == primaryClusterId {
|
||||
backupClusterId = 0
|
||||
}
|
||||
return primaryClusterId, backupClusterId, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (this *HTTPDNSAppService) UpdateHTTPDNSApp(ctx context.Context, req *pb.UpdateHTTPDNSAppRequest) (*pb.RPCSuccess, error) {
|
||||
@@ -161,13 +175,8 @@ func (this *HTTPDNSAppService) UpdateHTTPDNSApp(ctx context.Context, req *pb.Upd
|
||||
if userId > 0 {
|
||||
targetUserId = userId
|
||||
}
|
||||
primaryClusterId := req.PrimaryClusterId
|
||||
backupClusterId := req.BackupClusterId
|
||||
if primaryClusterId > 0 && backupClusterId == primaryClusterId {
|
||||
backupClusterId = 0
|
||||
}
|
||||
|
||||
err = models.SharedHTTPDNSAppDAO.UpdateApp(tx, req.AppDbId, req.Name, primaryClusterId, backupClusterId, req.IsOn, targetUserId)
|
||||
err = models.SharedHTTPDNSAppDAO.UpdateApp(tx, req.AppDbId, req.Name, req.ClusterIdsJSON, req.IsOn, targetUserId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/installers"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
@@ -114,7 +115,26 @@ func (this *HTTPDNSNodeService) FindHTTPDNSNode(ctx context.Context, req *pb.Fin
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.FindHTTPDNSNodeResponse{Node: toPBNode(node)}, nil
|
||||
|
||||
pbNode := toPBNode(node)
|
||||
|
||||
// 认证信息
|
||||
if pbNode != nil {
|
||||
login, loginErr := models.SharedNodeLoginDAO.FindEnabledNodeLoginWithNodeId(this.NullTx(), nodeconfigs.NodeRoleHTTPDNS, nodeId)
|
||||
if loginErr != nil {
|
||||
return nil, loginErr
|
||||
}
|
||||
if login != nil {
|
||||
pbNode.NodeLogin = &pb.NodeLogin{
|
||||
Id: int64(login.Id),
|
||||
Name: login.Name,
|
||||
Type: login.Type,
|
||||
Params: login.Params,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindHTTPDNSNodeResponse{Node: pbNode}, nil
|
||||
}
|
||||
|
||||
func (this *HTTPDNSNodeService) ListHTTPDNSNodes(ctx context.Context, req *pb.ListHTTPDNSNodesRequest) (*pb.ListHTTPDNSNodesResponse, error) {
|
||||
@@ -171,6 +191,31 @@ func (this *HTTPDNSNodeService) UpdateHTTPDNSNodeStatus(ctx context.Context, req
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateHTTPDNSNodeLogin 修改HTTPDNS节点登录信息
|
||||
func (this *HTTPDNSNodeService) UpdateHTTPDNSNodeLogin(ctx context.Context, req *pb.UpdateHTTPDNSNodeLoginRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if req.NodeLogin.Id <= 0 {
|
||||
loginId, createErr := models.SharedNodeLoginDAO.CreateNodeLogin(tx, nodeconfigs.NodeRoleHTTPDNS, req.NodeId, req.NodeLogin.Name, req.NodeLogin.Type, req.NodeLogin.Params)
|
||||
if createErr != nil {
|
||||
return nil, createErr
|
||||
}
|
||||
req.NodeLogin.Id = loginId
|
||||
}
|
||||
|
||||
err = models.SharedNodeLoginDAO.UpdateNodeLogin(tx, req.NodeLogin.Id, req.NodeLogin.Name, req.NodeLogin.Type, req.NodeLogin.Params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
func shouldTriggerHTTPDNSInstall(installStatusJSON []byte) bool {
|
||||
if len(installStatusJSON) == 0 {
|
||||
return false
|
||||
|
||||
@@ -83,12 +83,23 @@ func (this *HTTPDNSSandboxService) TestHTTPDNSResolve(ctx context.Context, req *
|
||||
RequestId: "rid-" + rands.HexString(12),
|
||||
}, nil
|
||||
}
|
||||
if req.ClusterId > 0 && req.ClusterId != int64(app.PrimaryClusterId) && req.ClusterId != int64(app.BackupClusterId) {
|
||||
return &pb.TestHTTPDNSResolveResponse{
|
||||
Code: "APP_CLUSTER_MISMATCH",
|
||||
Message: "当前应用未绑定到该集群 (主集群: " + strconv.FormatInt(int64(app.PrimaryClusterId), 10) + ", 备用集群: " + strconv.FormatInt(int64(app.BackupClusterId), 10) + ")",
|
||||
RequestId: "rid-" + rands.HexString(12),
|
||||
}, nil
|
||||
// 检查集群是否绑定
|
||||
appClusterIds := models.SharedHTTPDNSAppDAO.ReadAppClusterIds(app)
|
||||
if req.ClusterId > 0 {
|
||||
var found bool
|
||||
for _, cid := range appClusterIds {
|
||||
if cid == req.ClusterId {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return &pb.TestHTTPDNSResolveResponse{
|
||||
Code: "APP_CLUSTER_MISMATCH",
|
||||
Message: "当前应用未绑定到该集群",
|
||||
RequestId: "rid-" + rands.HexString(12),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
qtype := strings.ToUpper(strings.TrimSpace(req.Qtype))
|
||||
@@ -98,8 +109,8 @@ func (this *HTTPDNSSandboxService) TestHTTPDNSResolve(ctx context.Context, req *
|
||||
|
||||
// 获取集群服务域名
|
||||
clusterId := req.ClusterId
|
||||
if clusterId <= 0 {
|
||||
clusterId = int64(app.PrimaryClusterId)
|
||||
if clusterId <= 0 && len(appClusterIds) > 0 {
|
||||
clusterId = appClusterIds[0]
|
||||
}
|
||||
cluster, err := models.SharedHTTPDNSClusterDAO.FindEnabledCluster(this.NullTx(), clusterId)
|
||||
if err != nil {
|
||||
@@ -128,6 +139,25 @@ func (this *HTTPDNSSandboxService) TestHTTPDNSResolve(ctx context.Context, req *
|
||||
return nil, err
|
||||
}
|
||||
|
||||
port := "443"
|
||||
if len(cluster.TLSPolicy) > 0 {
|
||||
var tlsConfig map[string]interface{}
|
||||
if err := json.Unmarshal(cluster.TLSPolicy, &tlsConfig); err == nil {
|
||||
if listenRaw, ok := tlsConfig["listen"]; ok && listenRaw != nil {
|
||||
if data, err := json.Marshal(listenRaw); err == nil {
|
||||
var listenAddresses []map[string]interface{}
|
||||
if err := json.Unmarshal(data, &listenAddresses); err == nil {
|
||||
if len(listenAddresses) > 0 {
|
||||
if portRange, ok := listenAddresses[0]["portRange"].(string); ok && len(portRange) > 0 {
|
||||
port = portRange
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query := url.Values{}
|
||||
query.Set("appId", req.AppId)
|
||||
query.Set("dn", req.Domain)
|
||||
@@ -167,7 +197,7 @@ func (this *HTTPDNSSandboxService) TestHTTPDNSResolve(ctx context.Context, req *
|
||||
query.Set("sign", sign)
|
||||
}
|
||||
|
||||
resolveURL := "https://" + serviceDomain + "/resolve?" + query.Encode()
|
||||
resolveURL := "https://" + serviceDomain + ":" + port + "/resolve?" + query.Encode()
|
||||
|
||||
httpClient := &http.Client{
|
||||
Timeout: 5 * time.Second,
|
||||
|
||||
@@ -18,16 +18,14 @@ func notifyHTTPDNSAppTasksByApp(tx *dbs.Tx, app *models.HTTPDNSApp, taskType mod
|
||||
return nil
|
||||
}
|
||||
|
||||
primaryClusterId := int64(app.PrimaryClusterId)
|
||||
backupClusterId := int64(app.BackupClusterId)
|
||||
|
||||
err := notifyHTTPDNSClusterTask(tx, primaryClusterId, taskType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if backupClusterId > 0 && backupClusterId != primaryClusterId {
|
||||
err = notifyHTTPDNSClusterTask(tx, backupClusterId, taskType)
|
||||
clusterIds := models.SharedHTTPDNSAppDAO.ReadAppClusterIds(app)
|
||||
notified := map[int64]bool{}
|
||||
for _, clusterId := range clusterIds {
|
||||
if clusterId <= 0 || notified[clusterId] {
|
||||
continue
|
||||
}
|
||||
notified[clusterId] = true
|
||||
err := notifyHTTPDNSClusterTask(tx, clusterId, taskType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func (this *UserService) UpdateUser(ctx context.Context, req *pb.UpdateUserReque
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = models.SharedUserDAO.UpdateUser(tx, req.UserId, req.Username, req.Password, req.Fullname, req.Mobile, req.Tel, req.Email, req.Remark, req.IsOn, req.NodeClusterId, req.BandwidthAlgo)
|
||||
err = models.SharedUserDAO.UpdateUser(tx, req.UserId, req.Username, req.Password, req.Fullname, req.Mobile, req.Tel, req.Email, req.Remark, req.IsOn, req.NodeClusterId, req.BandwidthAlgo, req.HttpdnsClusterIdsJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -242,6 +242,20 @@ func (this *UserService) FindEnabledUser(ctx context.Context, req *pb.FindEnable
|
||||
}
|
||||
}
|
||||
|
||||
// 用户功能列表
|
||||
var pbFeatures []*pb.UserFeature
|
||||
userFeatures, err := models.SharedUserDAO.FindUserFeatures(tx, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, f := range userFeatures {
|
||||
pbFeatures = append(pbFeatures, &pb.UserFeature{
|
||||
Name: f.Name,
|
||||
Code: f.Code,
|
||||
Description: f.Description,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FindEnabledUserResponse{
|
||||
User: &pb.User{
|
||||
Id: int64(user.Id),
|
||||
@@ -265,6 +279,8 @@ func (this *UserService) FindEnabledUser(ctx context.Context, req *pb.FindEnable
|
||||
BandwidthAlgo: user.BandwidthAlgo,
|
||||
OtpLogin: pbOtpAuth,
|
||||
Lang: user.Lang,
|
||||
Features: pbFeatures,
|
||||
HttpdnsClusterIdsJSON: user.HttpdnsClusterIds,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -5,11 +5,13 @@ package users
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
)
|
||||
|
||||
// FindUserPriceInfo 读取用户计费信息
|
||||
@@ -142,13 +144,27 @@ func (this *UserService) RegisterUser(ctx context.Context, req *pb.RegisterUserR
|
||||
return errors.New("the username exists already")
|
||||
}
|
||||
|
||||
features := registerConfig.Features
|
||||
if registerConfig.HTTPDNSIsOn && !lists.ContainsString(features, userconfigs.UserFeatureCodeHTTPDNS) {
|
||||
features = append(features, userconfigs.UserFeatureCodeHTTPDNS)
|
||||
}
|
||||
|
||||
// 创建用户
|
||||
userId, err := models.SharedUserDAO.CreateUser(tx, req.Username, req.Password, req.Fullname, req.Mobile, "", req.Email, "", req.Source, registerConfig.ClusterId, registerConfig.Features, req.Ip, !registerConfig.RequireVerification)
|
||||
userId, err := models.SharedUserDAO.CreateUser(tx, req.Username, req.Password, req.Fullname, req.Mobile, "", req.Email, "", req.Source, registerConfig.ClusterId, features, req.Ip, !registerConfig.RequireVerification)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
createdUserId = userId
|
||||
|
||||
// 自动关联默认 HTTPDNS 集群
|
||||
if registerConfig.HTTPDNSIsOn && len(registerConfig.HTTPDNSDefaultClusterIds) > 0 {
|
||||
httpdnsJSON, _ := json.Marshal(registerConfig.HTTPDNSDefaultClusterIds)
|
||||
err = models.SharedUserDAO.UpdateUserHttpdnsClusterIds(tx, userId, httpdnsJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 发送激活邮件
|
||||
if len(req.Email) > 0 && registerConfig.EmailVerification.IsOn {
|
||||
_, err := models.SharedUserEmailVerificationDAO.CreateVerification(tx, userId, req.Email)
|
||||
|
||||
@@ -1258,14 +1258,27 @@ func upgradeV1_4_4(db *dbs.DB) error {
|
||||
|
||||
// 1.4.8
|
||||
func upgradeV1_4_8(db *dbs.DB) error {
|
||||
return createHTTPDNSTables(db)
|
||||
err := createHTTPDNSTables(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// edgeUsers: 增加 httpdnsClusterIds 字段
|
||||
_, alterErr := db.Exec("ALTER TABLE `edgeUsers` ADD COLUMN `httpdnsClusterIds` text DEFAULT NULL")
|
||||
if alterErr != nil {
|
||||
if strings.Contains(alterErr.Error(), "Duplicate column") {
|
||||
return nil
|
||||
}
|
||||
return alterErr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createHTTPDNSTables(db *dbs.DB) error {
|
||||
sqls := []string{
|
||||
"CREATE TABLE IF NOT EXISTS `edgeHTTPDNSClusters` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`isOn` tinyint unsigned DEFAULT '1',`isDefault` tinyint unsigned DEFAULT '0',`serviceDomain` varchar(255) DEFAULT NULL,`defaultTTL` int unsigned DEFAULT '30',`fallbackTimeoutMs` int unsigned DEFAULT '300',`installDir` varchar(255) DEFAULT '/opt/edge-httpdns',`tlsPolicy` json DEFAULT NULL,`createdAt` bigint unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),KEY `name` (`name`),KEY `isDefault` (`isDefault`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS集群配置表(默认TTL、回退超时、服务域名等)'",
|
||||
"CREATE TABLE IF NOT EXISTS `edgeHTTPDNSNodes` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`clusterId` bigint unsigned DEFAULT '0',`name` varchar(255) DEFAULT NULL,`isOn` tinyint unsigned DEFAULT '1',`isUp` tinyint unsigned DEFAULT '0',`isInstalled` tinyint unsigned DEFAULT '0',`isActive` tinyint unsigned DEFAULT '0',`uniqueId` varchar(64) DEFAULT NULL,`secret` varchar(64) DEFAULT NULL,`installDir` varchar(255) DEFAULT '/opt/edge-httpdns',`status` json DEFAULT NULL,`installStatus` json DEFAULT NULL,`createdAt` bigint unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),UNIQUE KEY `uniqueId` (`uniqueId`),KEY `clusterId` (`clusterId`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS节点表(节点基础信息与运行状态)'",
|
||||
"CREATE TABLE IF NOT EXISTS `edgeHTTPDNSApps` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`appId` varchar(64) DEFAULT NULL,`isOn` tinyint unsigned DEFAULT '1',`primaryClusterId` bigint unsigned DEFAULT '0',`backupClusterId` bigint unsigned DEFAULT '0',`sniMode` varchar(64) DEFAULT 'fixed_hide',`userId` bigint unsigned DEFAULT '0',`createdAt` bigint unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),UNIQUE KEY `appId` (`appId`),KEY `name` (`name`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS应用表(应用与主备集群绑定关系)'",
|
||||
"CREATE TABLE IF NOT EXISTS `edgeHTTPDNSApps` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`appId` varchar(64) DEFAULT NULL,`isOn` tinyint unsigned DEFAULT '1',`clusterIdsJSON` text DEFAULT NULL,`sniMode` varchar(64) DEFAULT 'fixed_hide',`userId` bigint unsigned DEFAULT '0',`createdAt` bigint unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),UNIQUE KEY `appId` (`appId`),KEY `name` (`name`),KEY `userId` (`userId`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS应用表(应用与集群绑定关系)'",
|
||||
"CREATE TABLE IF NOT EXISTS `edgeHTTPDNSAppSecrets` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`appId` bigint unsigned DEFAULT '0',`signEnabled` tinyint unsigned DEFAULT '0',`signSecret` varchar(255) DEFAULT NULL,`signUpdatedAt` bigint unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),UNIQUE KEY `appId` (`appId`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS应用密钥表(请求验签开关与加签Secret)'",
|
||||
"CREATE TABLE IF NOT EXISTS `edgeHTTPDNSDomains` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`appId` bigint unsigned DEFAULT '0',`domain` varchar(255) DEFAULT NULL,`isOn` tinyint unsigned DEFAULT '1',`createdAt` bigint unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),UNIQUE KEY `appId_domain` (`appId`,`domain`),KEY `domain` (`domain`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS应用域名表(应用绑定的业务域名)'",
|
||||
"CREATE TABLE IF NOT EXISTS `edgeHTTPDNSCustomRules` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`appId` bigint unsigned DEFAULT '0',`domainId` bigint unsigned DEFAULT '0',`ruleName` varchar(255) DEFAULT NULL,`lineScope` varchar(64) DEFAULT NULL,`lineCarrier` varchar(64) DEFAULT NULL,`lineRegion` varchar(64) DEFAULT NULL,`lineProvince` varchar(64) DEFAULT NULL,`lineContinent` varchar(64) DEFAULT NULL,`lineCountry` varchar(128) DEFAULT NULL,`ttl` int unsigned DEFAULT '30',`isOn` tinyint unsigned DEFAULT '1',`priority` int unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),KEY `domainId_isOn_priority` (`domainId`,`isOn`,`priority`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS自定义解析规则表(按线路/地域匹配)'",
|
||||
|
||||
Reference in New Issue
Block a user