221 lines
6.0 KiB
Go
221 lines
6.0 KiB
Go
package httpdns
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
|
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
|
"github.com/iwind/TeaGo/dbs"
|
|
)
|
|
|
|
func toPBCluster(cluster *models.HTTPDNSCluster) *pb.HTTPDNSCluster {
|
|
if cluster == nil {
|
|
return nil
|
|
}
|
|
return &pb.HTTPDNSCluster{
|
|
Id: int64(cluster.Id),
|
|
IsOn: cluster.IsOn > 0,
|
|
IsDefault: cluster.IsDefault > 0,
|
|
Name: cluster.Name,
|
|
ServiceDomain: cluster.ServiceDomain,
|
|
DefaultTTL: cluster.DefaultTTL,
|
|
FallbackTimeoutMs: cluster.FallbackTimeoutMs,
|
|
InstallDir: cluster.InstallDir,
|
|
TlsPolicyJSON: cluster.TLSPolicy,
|
|
CreatedAt: int64(cluster.CreatedAt),
|
|
UpdatedAt: int64(cluster.UpdatedAt),
|
|
AutoRemoteStart: cluster.AutoRemoteStart > 0,
|
|
AccessLogIsOn: cluster.AccessLogIsOn > 0,
|
|
TimeZone: cluster.TimeZone,
|
|
}
|
|
}
|
|
|
|
// toPBClusterWithResolvedCerts 转换集群并解析证书引用为实际 PEM 数据
|
|
// 供节点调用的 RPC 使用,确保节点能拿到完整的证书内容
|
|
func toPBClusterWithResolvedCerts(tx *dbs.Tx, cluster *models.HTTPDNSCluster) *pb.HTTPDNSCluster {
|
|
pbCluster := toPBCluster(cluster)
|
|
if pbCluster == nil {
|
|
return nil
|
|
}
|
|
resolved := resolveTLSPolicyCerts(tx, cluster.TLSPolicy)
|
|
if resolved != nil {
|
|
pbCluster.TlsPolicyJSON = resolved
|
|
}
|
|
return pbCluster
|
|
}
|
|
|
|
// resolveTLSPolicyCerts 将 tlsPolicyJSON 中的 certRefs 解析为带实际 PEM 数据的 certs
|
|
func resolveTLSPolicyCerts(tx *dbs.Tx, tlsPolicyJSON []byte) []byte {
|
|
if len(tlsPolicyJSON) == 0 {
|
|
return nil
|
|
}
|
|
|
|
// 解析外层结构: {"listen": [...], "sslPolicy": {...}}
|
|
var tlsConfig map[string]json.RawMessage
|
|
if err := json.Unmarshal(tlsPolicyJSON, &tlsConfig); err != nil {
|
|
return nil
|
|
}
|
|
|
|
sslPolicyData, ok := tlsConfig["sslPolicy"]
|
|
if !ok || len(sslPolicyData) == 0 {
|
|
return nil
|
|
}
|
|
|
|
var sslPolicy sslconfigs.SSLPolicy
|
|
if err := json.Unmarshal(sslPolicyData, &sslPolicy); err != nil {
|
|
return nil
|
|
}
|
|
|
|
// 检查 certs 是否已经有实际数据
|
|
for _, cert := range sslPolicy.Certs {
|
|
if cert != nil && len(cert.CertData) > 128 && len(cert.KeyData) > 128 {
|
|
return nil // 已有完整 PEM 数据,无需处理
|
|
}
|
|
}
|
|
|
|
// 从 certRefs 解析实际证书数据
|
|
if len(sslPolicy.CertRefs) == 0 {
|
|
return nil
|
|
}
|
|
|
|
var resolvedCerts []*sslconfigs.SSLCertConfig
|
|
for _, ref := range sslPolicy.CertRefs {
|
|
if ref == nil || ref.CertId <= 0 {
|
|
continue
|
|
}
|
|
certConfig, err := models.SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, false, nil, nil)
|
|
if err != nil {
|
|
log.Println("[HTTPDNS]resolve cert", ref.CertId, "failed:", err.Error())
|
|
continue
|
|
}
|
|
if certConfig == nil || len(certConfig.CertData) == 0 || len(certConfig.KeyData) == 0 {
|
|
continue
|
|
}
|
|
resolvedCerts = append(resolvedCerts, certConfig)
|
|
}
|
|
|
|
if len(resolvedCerts) == 0 {
|
|
return nil
|
|
}
|
|
|
|
// 把解析后的证书写回 sslPolicy.Certs
|
|
sslPolicy.Certs = resolvedCerts
|
|
|
|
newPolicyData, err := json.Marshal(&sslPolicy)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
tlsConfig["sslPolicy"] = newPolicyData
|
|
|
|
result, err := json.Marshal(tlsConfig)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return result
|
|
}
|
|
|
|
func toPBNode(node *models.HTTPDNSNode) *pb.HTTPDNSNode {
|
|
if node == nil {
|
|
return nil
|
|
}
|
|
return &pb.HTTPDNSNode{
|
|
Id: int64(node.Id),
|
|
ClusterId: int64(node.ClusterId),
|
|
Name: node.Name,
|
|
IsOn: node.IsOn,
|
|
IsUp: node.IsUp,
|
|
IsInstalled: node.IsInstalled,
|
|
IsActive: node.IsActive,
|
|
UniqueId: node.UniqueId,
|
|
Secret: node.Secret,
|
|
InstallDir: node.InstallDir,
|
|
StatusJSON: node.Status,
|
|
InstallStatusJSON: node.InstallStatus,
|
|
CreatedAt: int64(node.CreatedAt),
|
|
UpdatedAt: int64(node.UpdatedAt),
|
|
}
|
|
}
|
|
|
|
func toPBApp(app *models.HTTPDNSApp, secret *models.HTTPDNSAppSecret) *pb.HTTPDNSApp {
|
|
if app == nil {
|
|
return nil
|
|
}
|
|
var signEnabled bool
|
|
var signSecret string
|
|
var signUpdatedAt int64
|
|
if secret != nil {
|
|
signEnabled = secret.SignEnabled
|
|
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,
|
|
SniMode: app.SNIMode,
|
|
SignEnabled: signEnabled,
|
|
SignSecret: signSecret,
|
|
SignUpdatedAt: signUpdatedAt,
|
|
CreatedAt: int64(app.CreatedAt),
|
|
UpdatedAt: int64(app.UpdatedAt),
|
|
UserId: int64(app.UserId),
|
|
ClusterIdsJSON: clusterIdsJSON,
|
|
}
|
|
}
|
|
|
|
func toPBDomain(domain *models.HTTPDNSDomain, ruleCount int64) *pb.HTTPDNSDomain {
|
|
if domain == nil {
|
|
return nil
|
|
}
|
|
return &pb.HTTPDNSDomain{
|
|
Id: int64(domain.Id),
|
|
AppId: int64(domain.AppId),
|
|
Domain: domain.Domain,
|
|
IsOn: domain.IsOn,
|
|
CreatedAt: int64(domain.CreatedAt),
|
|
UpdatedAt: int64(domain.UpdatedAt),
|
|
RuleCount: ruleCount,
|
|
}
|
|
}
|
|
|
|
func toPBRule(rule *models.HTTPDNSCustomRule, records []*models.HTTPDNSCustomRuleRecord) *pb.HTTPDNSCustomRule {
|
|
if rule == nil {
|
|
return nil
|
|
}
|
|
var pbRecords []*pb.HTTPDNSRuleRecord
|
|
for _, record := range records {
|
|
pbRecords = append(pbRecords, &pb.HTTPDNSRuleRecord{
|
|
Id: int64(record.Id),
|
|
RuleId: int64(record.RuleId),
|
|
RecordType: record.RecordType,
|
|
RecordValue: record.RecordValue,
|
|
Weight: record.Weight,
|
|
Sort: record.Sort,
|
|
})
|
|
}
|
|
return &pb.HTTPDNSCustomRule{
|
|
Id: int64(rule.Id),
|
|
AppId: int64(rule.AppId),
|
|
DomainId: int64(rule.DomainId),
|
|
RuleName: rule.RuleName,
|
|
LineScope: rule.LineScope,
|
|
LineCarrier: rule.LineCarrier,
|
|
LineRegion: rule.LineRegion,
|
|
LineProvince: rule.LineProvince,
|
|
LineContinent: rule.LineContinent,
|
|
LineCountry: rule.LineCountry,
|
|
Ttl: rule.TTL,
|
|
IsOn: rule.IsOn,
|
|
Priority: rule.Priority,
|
|
UpdatedAt: int64(rule.UpdatedAt),
|
|
Records: pbRecords,
|
|
}
|
|
}
|