Browse Source

更新域名配置以支持多个域名集合

将域名配置从单个域名改为支持多个域名集合,并相应地更新了服务器、阿里云操作和配置文件的处理逻辑。增加了对域名集合的遍历和错误处理,确保每个域名都能正确更新CDN的HTTPS设置。
SongZihuan 3 tháng trước cách đây
mục cha
commit
f7aaabccc7
5 tập tin đã thay đổi với 77 bổ sung49 xóa
  1. 9 9
      src/aliyun/main.go
  2. 21 4
      src/aliyun/operation.go
  3. 35 25
      src/config/domainconfg.go
  4. 4 4
      src/config/yamlconfig.go
  5. 8 7
      src/server/server.go

+ 9 - 9
src/aliyun/main.go

@@ -6,6 +6,7 @@ import (
 	"github.com/SongZihuan/auto-aliyun-cdn-ssl/src/config"
 	"github.com/SongZihuan/auto-aliyun-cdn-ssl/src/logger"
 	"os"
+	"strings"
 )
 
 var international = false
@@ -32,7 +33,7 @@ func Init() (err error) {
 	return nil
 }
 
-func UpdateCDNHttpsByFilePath(domain string, cert string, prikey string) error {
+func UpdateCDNHttpsByFilePath(domainList []string, cert string, prikey string) error {
 	certData, err := os.ReadFile(cert)
 	if err != nil {
 		return fmt.Errorf("read cert file error: %s\n", err.Error())
@@ -43,21 +44,20 @@ func UpdateCDNHttpsByFilePath(domain string, cert string, prikey string) error {
 		return fmt.Errorf("read private key error: %s\n", err.Error())
 	}
 
-	return UpdateCDNHttps(domain, certData, privateKeyData)
+	return UpdateCDNHttps(domainList, certData, privateKeyData)
 }
 
-func UpdateCDNHttps(domain string, certData []byte, privateKeyData []byte) error {
-	certID, certName, err := uploadCert(casClient, certData, privateKeyData)
+func UpdateCDNHttps(domainList []string, certData []byte, privateKeyData []byte) error {
+	certID, certName, err := uploadCert(certData, privateKeyData)
 	if err != nil && errors.Is(err, ErrCertExists) {
-		logger.Warn("证书已存在, 不在重新更新CDN")
+		logger.Warnf("证书已存在, 不在重新更新CDN(%s)", strings.Join(domainList, ", "))
 		return nil
 	} else if err != nil {
-		return fmt.Errorf("upload error: %s\n", err.Error())
+		return fmt.Errorf("aliyun cloud ssl cert/key upload error: %s\n", err.Error())
 	}
 
-	err = setDomainServerCertificate(cdnClient, domain, certID, certName)
-	if err != nil {
-		return err
+	for _, domain := range domainList {
+		setDomainServerCertificateNotError(domain, certID, certName)
 	}
 
 	return nil

+ 21 - 4
src/aliyun/operation.go

@@ -13,7 +13,7 @@ import (
 	"strings"
 )
 
-func uploadCert(client *cas.Client, certData []byte, keyData []byte) (certID int64, name string, err error) {
+func uploadCert(certData []byte, keyData []byte) (certID int64, name string, err error) {
 	cert, err := utils.ReadCertificate(certData)
 	if err != nil {
 		panic(err)
@@ -35,7 +35,7 @@ func uploadCert(client *cas.Client, certData []byte, keyData []byte) (certID int
 			}
 		}()
 
-		return client.UploadUserCertificateWithOptions(uploadUserCertificateRequest, &util.RuntimeOptions{})
+		return casClient.UploadUserCertificateWithOptions(uploadUserCertificateRequest, &util.RuntimeOptions{})
 	}()
 	if tryErr != nil {
 		var sdkErr *tea.SDKError
@@ -49,7 +49,7 @@ func uploadCert(client *cas.Client, certData []byte, keyData []byte) (certID int
 	return tea.Int64Value(resp.Body.CertId), fingerprint, nil
 }
 
-func setDomainServerCertificate(client *cdn.Client, domainName string, certID int64, certName string) (err error) {
+func setDomainServerCertificate(domainName string, certID int64, certName string) (err error) {
 	request := &cdn.SetCdnDomainSSLCertificateRequest{}
 	request.DomainName = tea.String(strings.TrimPrefix(domainName, "*")) // 泛域名去除星号
 	request.CertName = tea.String(certName)
@@ -69,7 +69,7 @@ func setDomainServerCertificate(client *cdn.Client, domainName string, certID in
 			}
 		}()
 
-		return client.SetCdnDomainSSLCertificate(request)
+		return cdnClient.SetCdnDomainSSLCertificate(request)
 	}()
 	if tryErr != nil {
 		return tryErr
@@ -77,3 +77,20 @@ func setDomainServerCertificate(client *cdn.Client, domainName string, certID in
 	logger.Infof("CDN加速域名(%s)证书(%s)更新成功, 并启用SSL", domainName, certName)
 	return nil
 }
+
+func setDomainServerCertificateNotError(domainName string, certID int64, certName string) {
+	defer func() {
+		if r := recover(); r != nil {
+			if err, ok := r.(error); ok {
+				logger.Panicf("aliyun update CDN HTTPS by domains/collection (%s) panic: %s", domainName, err.Error())
+			} else {
+				logger.Panicf("aliyun update CDN HTTPS by domains/collection (%s) panic: %v", domainName, r)
+			}
+		}
+	}()
+
+	err := setDomainServerCertificate(domainName, certID, certName)
+	if err != nil {
+		logger.Infof("CDN加速域名(%s)证书(%s)更新失败:%s", domainName, certName, err.Error())
+	}
+}

+ 35 - 25
src/config/domainconfg.go

@@ -1,25 +1,26 @@
 package config
 
 import (
+	"fmt"
 	"github.com/SongZihuan/auto-aliyun-cdn-ssl/src/baota"
 	"github.com/SongZihuan/auto-aliyun-cdn-ssl/src/utils"
 	"path"
+	"path/filepath"
 )
 
-type Domain struct {
-	Domain  string `yaml:"domain"`
-	RootDir string `yaml:"-"`
-	Dir     string `yaml:"dir"`
-	Cert    string `yaml:"cert"`
-	Key     string `yaml:"pri"`
+type DomainListCollection struct {
+	Domain []string `yaml:"domain"`
+	Dir    string   `yaml:"dir"`
+	Cert   string   `yaml:"cert"`
+	Key    string   `yaml:"pri"`
 }
 
-type DomainConfig struct {
-	RootDir string   `yaml:"rootrir"`
-	Domains []Domain `yaml:"domains"`
+type DomainListsGroup struct {
+	RootDir    string                 `yaml:"rootrir"`
+	Collection []DomainListCollection `yaml:"collection"`
 }
 
-func (d *DomainConfig) SetDefault(configPath string) {
+func (d *DomainListsGroup) SetDefault(configPath string) {
 	if d.RootDir == "" {
 		if baota.HasBaoTaLetsEncrypt() {
 			d.RootDir = baota.GetBaoTaLetsEncryptDir()
@@ -27,41 +28,50 @@ func (d *DomainConfig) SetDefault(configPath string) {
 			d.RootDir = path.Dir(configPath)
 		}
 	}
-
-	for _, domain := range d.Domains {
-		domain.RootDir = d.RootDir
-	}
-
 	return
 }
 
-func (d *DomainConfig) Check() ConfigError {
+func (d *DomainListsGroup) Check() ConfigError {
 	if !utils.IsDir(d.RootDir) {
 		return NewConfigError("root dir is not a dir")
 	}
 
-	for _, domain := range d.Domains {
-		if domain.Domain == "" {
-			return NewConfigError("domain is empty")
-		} else if !utils.IsValidDomain(domain.Domain) && !utils.IsValidWildcardDomain(domain.Domain) {
-			return NewConfigError("domain is not valid")
+	for _, domainLst := range d.Collection {
+		if len(domainLst.Domain) == 0 {
+			return NewConfigError("domain list is empty")
+		}
+
+		for _, domain := range domainLst.Domain {
+			if domain == "" {
+				return NewConfigError("domain is empty")
+			} else if !utils.IsValidDomain(domain) && !utils.IsValidWildcardDomain(domain) {
+				return NewConfigError("domain is not valid")
+			}
 		}
 	}
 
 	return nil
 }
 
-func (d *Domain) GetFilePath() (certPath string, prikeyPath string) {
-	rootDir := d.RootDir
+func (d *DomainListCollection) GetFilePath() (certPath string, prikeyPath string) {
+	if !IsReady() {
+		panic("config is not ready")
+	}
+
+	rootDir := GetConfig().RootDir
+
+	if baota.IsLinuxBaoTa() && rootDir != baota.GetBaoTaLetsEncryptDir() {
+		fmt.Printf("提示:运行在宝塔环境,但非Let's Encrypt目录")
+	}
 
 	if d.Dir != "" {
-		if path.IsAbs(d.Dir) {
+		if filepath.IsAbs(d.Dir) {
 			rootDir = d.Dir
 		} else {
 			rootDir = path.Join(rootDir, d.Dir)
 		}
 	} else {
-		rootDir = path.Join(rootDir, d.Domain)
+		rootDir = path.Join(rootDir, d.Domain[0])
 	}
 
 	if rootDir == "" {

+ 4 - 4
src/config/yamlconfig.go

@@ -6,8 +6,8 @@ import (
 )
 
 type YamlConfig struct {
-	GlobalConfig `yaml:",inline"`
-	DomainConfig `yaml:",inline"`
+	GlobalConfig     `yaml:",inline"`
+	DomainListsGroup `yaml:",inline"`
 
 	Aliyun AliyunConfig `yaml:"aliyun"`
 }
@@ -18,7 +18,7 @@ func (y *YamlConfig) Init() error {
 
 func (y *YamlConfig) SetDefault(configPath string) {
 	y.GlobalConfig.SetDefault()
-	y.DomainConfig.SetDefault(configPath)
+	y.DomainListsGroup.SetDefault(configPath)
 	y.Aliyun.SetDefault()
 }
 
@@ -28,7 +28,7 @@ func (y *YamlConfig) Check() (err ConfigError) {
 		return err
 	}
 
-	err = y.DomainConfig.Check()
+	err = y.DomainListsGroup.Check()
 	if err != nil && err.IsError() {
 		return err
 	}

+ 8 - 7
src/server/server.go

@@ -4,28 +4,29 @@ import (
 	"github.com/SongZihuan/auto-aliyun-cdn-ssl/src/aliyun"
 	"github.com/SongZihuan/auto-aliyun-cdn-ssl/src/config"
 	"github.com/SongZihuan/auto-aliyun-cdn-ssl/src/logger"
+	"strings"
 )
 
 func Server() error {
-	cfg := config.GetConfig().DomainConfig
+	cfg := config.GetConfig().DomainListsGroup
 
 	logger.Info("Server start...")
-	for _, domain := range cfg.Domains {
+	for index, collection := range cfg.Collection {
 		func() {
 			defer func() {
 				if r := recover(); r != nil {
 					if err, ok := r.(error); ok {
-						logger.Panicf("aliyun update CDN HTTOS by domain (%s) panic: %s", domain, err.Error())
+						logger.Panicf("aliyun update CDN HTTPS by domains/collection (%s / %d) panic: %s", strings.Join(collection.Domain, ", "), index, err.Error())
 					} else {
-						logger.Panicf("aliyun update CDN HTTOS by domain (%s) panic: %v", domain, r)
+						logger.Panicf("aliyun update CDN HTTPS by domains/collection (%s / %d) panic: %v", strings.Join(collection.Domain, ", "), index, r)
 					}
 				}
 			}()
 
-			certPath, prikeyPath := domain.GetFilePath()
-			err := aliyun.UpdateCDNHttpsByFilePath(domain.Domain, certPath, prikeyPath)
+			certPath, prikeyPath := collection.GetFilePath()
+			err := aliyun.UpdateCDNHttpsByFilePath(collection.Domain, certPath, prikeyPath)
 			if err != nil {
-				logger.Errorf("aliyun update CDN HTTOS by domain (%s) error: %s", domain, err.Error())
+				logger.Panicf("aliyun update CDN HTTPS by domains/collection (%s / %d) panic: %s", strings.Join(collection.Domain, ", "), index, err.Error())
 			}
 		}()
 	}