Skip to content

Commit b392085

Browse files
committed
重构证书部署逻辑,检查 SSL 目录配置。添加了公共 IP 检索功能,并改进了证书部署过程中的错误处理。更新了配置结构标签,以实现 YAML 兼容性。
1 parent 90c1481 commit b392085

File tree

3 files changed

+106
-31
lines changed

3 files changed

+106
-31
lines changed

internal/client/cert_deploy.go

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,32 +46,38 @@ func (cd *CertDeployer) DeployCertificate(domain, url string) error {
4646

4747
fmt.Printf("证书下载完成: %s\n", zipFile)
4848

49-
// 证书文件夹名
50-
folderName := domain + "_certificates"
49+
// 2. 检查是否配置了SSL目录
50+
sslPath := config.GetConfig().SSL.Path
51+
if sslPath != "" {
52+
// 证书文件夹名
53+
folderName := domain + "_certificates"
54+
55+
// 1. 解压zip文件
56+
extractDir := filepath.Join(certsDir, folderName)
57+
if err := cd.extractZip(zipFile, extractDir); err != nil {
58+
return fmt.Errorf("解压证书失败: %w", err)
59+
}
5160

52-
// 1. 解压zip文件
53-
extractDir := filepath.Join(certsDir, folderName)
54-
if err := cd.extractZip(zipFile, extractDir); err != nil {
55-
return fmt.Errorf("解压证书失败: %w", err)
56-
}
61+
// 移动到配置的SSL目录
62+
if err := cd.moveCertificates(extractDir, sslPath, folderName); err != nil {
63+
return fmt.Errorf("移动证书失败: %w", err)
64+
}
5765

58-
// 2. 移动到配置的SSL目录
59-
sslPath := config.GetConfig().SSL.Path
60-
if err := cd.moveCertificates(extractDir, sslPath, folderName); err != nil {
61-
return fmt.Errorf("移动证书失败: %w", err)
62-
}
66+
// 3. 测试nginx配置
67+
if err := cd.testNginxConfig(); err != nil {
68+
return fmt.Errorf("nginx配置测试失败: %w", err)
69+
}
6370

64-
// 3. 测试nginx配置
65-
if err := cd.testNginxConfig(); err != nil {
66-
return fmt.Errorf("nginx配置测试失败: %w", err)
67-
}
71+
// 4. 重新加载nginx
72+
if err := cd.reloadNginx(); err != nil {
73+
return fmt.Errorf("nginx重新加载失败: %w", err)
74+
}
75+
fmt.Printf("证书部署完成: %s\n", domain)
6876

69-
// 4. 重新加载nginx
70-
if err := cd.reloadNginx(); err != nil {
71-
return fmt.Errorf("nginx重新加载失败: %w", err)
77+
} else {
78+
fmt.Println("未配置SSL目录,证书已下载到: ", zipFile)
7279
}
7380

74-
fmt.Printf("证书部署完成: %s\n", domain)
7581
return nil
7682
}
7783

internal/config/config.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,27 @@ import (
99
)
1010

1111
var (
12-
Config *Configuration
13-
Version = "v0.0.1"
14-
URL = URLLocal
15-
// URL = URLProd
12+
Config *Configuration
13+
Version = "v0.0.1"
14+
URL = URLProd
1615
URLProd = "https://cert.yzys.cc/deploy"
1716
URLLocal = "http://localhost:9000/deploy"
1817
)
1918

2019
// Configuration 应用配置结构
2120
type Configuration struct {
22-
Server ServerConfig `mapstructure:"server"`
23-
SSL SSLConfig `mapstructure:"ssl"`
21+
Server ServerConfig `yaml:"server"`
22+
SSL SSLConfig `yaml:"ssl"`
2423
}
2524

2625
type (
2726
ServerConfig struct {
28-
AccessKey string `mapstructure:"accessKey"`
27+
AccessKey string `yaml:"accessKey"`
28+
Env string `yaml:"env"`
2929
}
3030

3131
SSLConfig struct {
32-
Path string `mapstructure:"path"`
32+
Path string `yaml:"path"`
3333
}
3434
)
3535

@@ -68,6 +68,10 @@ func validateConfig() error {
6868
}
6969
}
7070

71+
if Config.Server.Env == "local" {
72+
URL = URLLocal
73+
}
74+
7175
return nil
7276
}
7377

internal/system/info.go

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"crypto/sha256"
66
"encoding/hex"
77
"fmt"
8+
"io"
89
"net"
10+
"net/http"
911
"os"
1012
"os/exec"
1113
"path/filepath"
@@ -36,9 +38,11 @@ func GetSystemInfo() (*SystemInfo, error) {
3638
info.Hostname = hostname
3739
}
3840

39-
// 获取本机IP
40-
if ip := getLocalIP(); ip != "" {
41-
info.IP = ip
41+
// 获取IP地址(优先公网IP,失败则使用内网IP)
42+
if publicIP := getPublicIP(); publicIP != "" {
43+
info.IP = publicIP
44+
} else if localIP := getLocalIP(); localIP != "" {
45+
info.IP = localIP
4246
}
4347

4448
return info, nil
@@ -360,3 +364,64 @@ func trimNL(b []byte) []byte {
360364
}
361365
return b
362366
}
367+
368+
// getPublicIP 获取公网IP地址
369+
func getPublicIP() string {
370+
// 使用多个服务提供商,提高成功率
371+
services := []string{
372+
"https://checkip.amazonaws.com",
373+
"https://ifconfig.me/ip",
374+
"https://api.ipify.org",
375+
"https://ipv4.icanhazip.com",
376+
"https://api.ip.sb/ip", // 国内可能无法访问
377+
}
378+
379+
for _, service := range services {
380+
if ip := getIPFromService(service); ip != "" {
381+
return ip
382+
}
383+
}
384+
return ""
385+
}
386+
387+
// getIPFromService 从指定服务获取IP地址
388+
func getIPFromService(serviceURL string) string {
389+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
390+
defer cancel()
391+
392+
client := &http.Client{
393+
Timeout: 5 * time.Second,
394+
}
395+
396+
req, err := http.NewRequestWithContext(ctx, "GET", serviceURL, nil)
397+
if err != nil {
398+
return ""
399+
}
400+
401+
// 设置User-Agent,避免被某些服务拒绝
402+
req.Header.Set("User-Agent", "cert-deploy-client/1.0")
403+
404+
resp, err := client.Do(req)
405+
if err != nil {
406+
return ""
407+
}
408+
defer resp.Body.Close()
409+
410+
if resp.StatusCode != http.StatusOK {
411+
return ""
412+
}
413+
414+
body, err := io.ReadAll(resp.Body)
415+
if err != nil {
416+
return ""
417+
}
418+
419+
ip := strings.TrimSpace(string(body))
420+
421+
// 验证IP地址格式
422+
if net.ParseIP(ip) != nil {
423+
return ip
424+
}
425+
426+
return ""
427+
}

0 commit comments

Comments
 (0)