diff --git a/Makefile b/Makefile index fd03b2f..efb165e 100644 --- a/Makefile +++ b/Makefile @@ -1,50 +1,49 @@ -# 定义变量 +# Define variables BIN_DIR := ./bin APP_NAME := safelineApi SRC_DIR := ./cmd/safelineApi VERSION := 1.0.0 BUILD_TIME := $(shell date +"%Y-%m-%dT%H:%M:%S") -# 默认任务 .DEFAULT_GOAL := build -# 构建任务 +# Build task build: @echo "Building $(APP_NAME) version $(VERSION)..." mkdir -p $(BIN_DIR) go build -ldflags "-X main.Version=$(VERSION) -X main.BuildTime=$(BUILD_TIME)" -o $(BIN_DIR)/$(APP_NAME) $(SRC_DIR) -# 运行任务 +# Run task run: @echo "Running $(APP_NAME)..." $(BIN_DIR)/$(APP_NAME) -# 清理任务 +# Clean task clean: @echo "Cleaning up..." rm -rf $(BIN_DIR) -# 测试任务 +# Test task test: @echo "Running tests..." go test ./... -# 格式化代码 +# Format code fmt: @echo "Formatting code..." go fmt ./... -# 检查代码风格 +# Vet code vet: @echo "Vetting code..." go vet ./... -# 安装依赖 +# Install dependencies tidy: @echo "Tidying dependencies..." go mod tidy -# 多平台编译 +# Cross-platform build build-all: @echo "Building for all platforms..." GOOS=linux GOARCH=amd64 go build -o $(BIN_DIR)/$(APP_NAME)-linux-amd64 $(SRC_DIR) diff --git a/cmd/safelineApi/config.json b/cmd/safelineApi/config.json new file mode 100644 index 0000000..5c014db --- /dev/null +++ b/cmd/safelineApi/config.json @@ -0,0 +1,41 @@ +{ + "SafeLine": { + "Host": { + "HostName": "192.168.1.4", + "Port": "1443" + }, + "ApiToken": "xxx" + }, + "ApplyCert": { + "Days": 30, + "Email": "xxx", + "SavePath": "/tmp/ssl", + "DNSProviderConfig": { + "DNSProvider": "xxx", + "TencentCloud": { + "SecretId": "xxx", + "SecretKey": "xxx" + }, + "AliCloud": { + "AccessKeyId": "xxx", + "AccessKeySecret": "xxx", + "RAMRole": "xxx (optional)", + "STSToken": "xxx (optional)" + }, + "HuaweiCloud": { + "AccessKeyId": "xxx", + "Region": "xxx", + "SecretAccessKey": "xxx" + }, + "WestCN": { + "Username": "xxx", + "Password": "xxx" + }, + "RainYun": { + "ApiKey": "xxx" + }, + "Cloudflare": {}, + "Dode": {} + } + } +} \ No newline at end of file diff --git a/cmd/safelineApi/main.go b/cmd/safelineApi/main.go index 79bc22d..f62201a 100644 --- a/cmd/safelineApi/main.go +++ b/cmd/safelineApi/main.go @@ -24,7 +24,7 @@ func main() { err := os.MkdirAll(conf.SavePath, os.ModePerm) if err != nil { - logger.Error.Printf("创建文件夹 %s%s%s 时发生错误: %s%s%s", logger.Cyan, conf.SavePath, logger.Reset, logger.Red, err.Error(), logger.Reset) + logger.Error.Printf("Error creating folder %s%s%s: %s%s%s", logger.Cyan, conf.SavePath, logger.Reset, logger.Red, err.Error(), logger.Reset) } urlStr := conf.Url() @@ -32,10 +32,10 @@ func main() { certUpsert := moudle.CheckNodes(certNodes, conf.Days) p, err := moudle.ChooseDNSProvider(conf.DNSProviderConfig) if err != nil { - logger.Error.Println(fmt.Sprintf("验证 DNS 服务提供商时发生错误: %s%s%s", logger.Red, err, logger.Reset)) + logger.Error.Println(fmt.Sprintf("Error validating DNS provider: %s%s%s", logger.Red, err, logger.Reset)) os.Exit(0) } - log.Printf("本次需要更新证书数量有 %d 个", len(certUpsert)) + log.Printf("Number of certificates to update this run: %d", len(certUpsert)) var failedApply [][]string var successApply [][]string for _, cert := range certUpsert { @@ -48,20 +48,20 @@ func main() { body := bytes.NewReader(upsertReq.Marshal()) result := utils.Upsert(urlStr, conf.ApiToken.String(), body) if result.Msg != "" { - logger.Error.Printf("域名 %s%s%s 证书更新失败: %s%s%s", logger.Cyan, cert.Domains, logger.Reset, logger.Red, result.Msg, logger.Reset) + logger.Error.Printf("Certificate update failed for domain %s%s%s: %s%s%s", logger.Cyan, cert.Domains, logger.Reset, logger.Red, result.Msg, logger.Reset) failedApply = append(failedApply, cert.Domains) continue } successApply = append(successApply, cert.Domains) - logger.Success.Printf("域名 %s%s%s 证书更新成功!", logger.Cyan, cert.Domains, logger.Reset) + logger.Success.Printf("Certificate update succeeded for domain %s%s%s", logger.Cyan, cert.Domains, logger.Reset) } if len(successApply) != 0 { - log.Printf("本次成功更新的域名证书如下: %s%s%s", logger.Cyan, successApply, logger.Reset) + log.Printf("Certificates successfully updated this run: %s%s%s", logger.Cyan, successApply, logger.Reset) } if len(failedApply) != 0 { - log.Printf("未成功更新的域名证书如下: %s%s%s", logger.Cyan, failedApply, logger.Reset) + log.Printf("Certificates that failed to update: %s%s%s", logger.Cyan, failedApply, logger.Reset) } - log.Printf("本次任务执行完成") + log.Printf("Task completed") _ = os.RemoveAll(conf.SavePath) } diff --git a/config.json b/config.json index 8b4d9c2..9723e78 100644 --- a/config.json +++ b/config.json @@ -19,8 +19,8 @@ "AliCloud": { "AccessKeyId": "xxx", "AccessKeySecret": "xxx", - "RAMRole": "xxx(可选)", - "STSToken": "xxx(可选)" + "RAMRole": "xxx (optional)", + "STSToken": "xxx (optional)" }, "HuaweiCloud": { "AccessKeyId": "xxx", diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 860e7b6..140f38d 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -64,7 +64,7 @@ go run ./cmd/safelineApi -- -t "" -D "Cloudflare" -e "you@exam Notes on flags: the project reads flags and `config.json`. If a flag is present it will be used for that run. **Troubleshooting** -- Warning about missing values: If you see warnings like `未设置 DNS服务提供商`, set `ApplyCert.DNSProviderConfig.DNSProvider` or pass `-D` on the command line. + - Warning about missing values: If you see warnings like `No DNS provider set`, set `ApplyCert.DNSProviderConfig.DNSProvider` or pass `-D` on the command line. - Dependency/download issues: If `go build` stalls on module downloads, try setting a proxy: ```powershell go env -w GOPROXY=https://goproxy.cn,direct diff --git a/internal/app/config/Config.go b/internal/app/config/Config.go index 8ce8580..bdc0b14 100644 --- a/internal/app/config/Config.go +++ b/internal/app/config/Config.go @@ -15,12 +15,12 @@ type Config struct { func (config *Config) Read(path string) { data, err := os.ReadFile(path) if err != nil { - logger.Error.Printf("配置文件读取失败: %s%s%s", logger.Red, err, logger.Reset) + logger.Error.Printf("Failed to read configuration file: %s%s%s", logger.Red, err, logger.Reset) os.Exit(0) } err = json.Unmarshal(data, &config) if err != nil { - logger.Error.Printf("配置文件读取失败: %s%s%s", logger.Red, err, logger.Reset) + logger.Error.Printf("Failed to read configuration file: %s%s%s", logger.Red, err, logger.Reset) os.Exit(0) } config.Verify() diff --git a/internal/app/config/applyCert.go b/internal/app/config/applyCert.go index d44f763..21aff1c 100644 --- a/internal/app/config/applyCert.go +++ b/internal/app/config/applyCert.go @@ -31,15 +31,15 @@ func (applyCert *ApplyCert) Verify() bool { } if applyCert.DNSProvider == "" { - logger.Warning.Printf("未设置 %sDNS服务提供商%s: 请检查配置文件中的 %sApplyCert.DNSProviderConfig.DNSProvider%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) + logger.Warning.Printf("No %sDNS provider%s set: please check the %sApplyCert.DNSProviderConfig.DNSProvider%s parameter", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) flag = true } if applyCert.Email == "" { - logger.Warning.Printf("未设置 %s证书申请邮箱%s: 请检查配置文件中的 %sApplyCert.Email%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) + logger.Warning.Printf("No %scertificate request email%s set: please check the %sApplyCert.Email%s parameter", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) flag = true } if !flag { - log.Printf("%sApplyCert%s 相关配置检验完成!", logger.Cyan, logger.Reset) + log.Printf("%sApplyCert%s configuration check completed!", logger.Cyan, logger.Reset) } return flag } @@ -55,15 +55,15 @@ func (applyCert *ApplyCert) VerifyCommand() bool { } if applyCert.DNSProvider == "" { - logger.Warning.Printf("未设置 %sDNS服务提供商%s: 请检查命令中的 %s-D%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) + logger.Warning.Printf("No %sDNS provider%s set: please check the %s-D%s command-line argument", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) flag = true } if applyCert.Email == "" { - logger.Warning.Printf("未设置 %s证书申请邮箱%s: 请检查命令中的 %s-e%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) + logger.Warning.Printf("No %scertificate request email%s set: please check the %s-e%s command-line argument", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) flag = true } if !flag { - log.Printf("%sApplyCert%s 相关配置检验完成!", logger.Cyan, logger.Reset) + log.Printf("%sApplyCert%s configuration check completed!", logger.Cyan, logger.Reset) } return flag diff --git a/internal/app/config/default.go b/internal/app/config/default.go index 6d7a606..2f0e689 100644 --- a/internal/app/config/default.go +++ b/internal/app/config/default.go @@ -22,8 +22,8 @@ func (config *Config) Default() { AliCloud: AliCloud{ AccessKeyId: "xxx", AccessKeySecret: "xxx", - RAMRole: "xxx(可选)", - STSToken: "xxx(可选)", + RAMRole: "xxx (optional)", + STSToken: "xxx (optional)", }, HuaweiCloud: HuaweiCloud{ AccessKeyId: "xxx", diff --git a/internal/app/config/host.go b/internal/app/config/host.go index 7b46d14..794334a 100644 --- a/internal/app/config/host.go +++ b/internal/app/config/host.go @@ -21,7 +21,7 @@ func (host Host) String() string { func (host Host) Verify() bool { if host.HostName == "" { - logger.Warning.Printf("未设置 %s主机名称%s: 请检查配置文件中的 %sSafeLine.Host.HostName%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) + logger.Warning.Printf("No %shostname%s set: please check the %sSafeLine.Host.HostName%s parameter", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) return true } return false @@ -29,7 +29,7 @@ func (host Host) Verify() bool { func (host Host) VerifyCommand() bool { if host.HostName == "" { - logger.Warning.Printf("未设置 %s主机名称%s: 请检查命令中的 %s-h%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) + logger.Warning.Printf("No %shostname%s set: please check the %s-h%s command-line argument", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) return true } return false diff --git a/internal/app/config/method.go b/internal/app/config/method.go index 1f5737c..21923ff 100644 --- a/internal/app/config/method.go +++ b/internal/app/config/method.go @@ -9,18 +9,18 @@ func (config *Config) Verify() { a := config.SafeLine.Verify() b := config.ApplyCert.Verify() if a || b { - log.Printf("配置检查完毕,请检查相关配置后重新运行!") + log.Printf("Configuration check complete; please review settings and rerun!") os.Exit(0) } - log.Printf("配置检查完毕,即将开始更新证书!") + log.Printf("Configuration check complete; starting certificate updates!") } func (config *Config) VerifyCommand() { a := config.SafeLine.VerifyCommand() b := config.ApplyCert.VerifyCommand() if a || b { - log.Printf("配置检查完毕,请检查相关配置后重新运行!") + log.Printf("Configuration check complete; please review settings and rerun!") os.Exit(0) } - log.Printf("配置检查完毕,即将开始更新证书!") + log.Printf("Configuration check complete; starting certificate updates!") } diff --git a/internal/app/config/safeline.go b/internal/app/config/safeline.go index dba34d5..849e22d 100644 --- a/internal/app/config/safeline.go +++ b/internal/app/config/safeline.go @@ -21,7 +21,7 @@ func (apiToken ApiToken) String() string { func (apiToken ApiToken) Verify() bool { if apiToken.String() == "" { - logger.Warning.Printf("未设置 %sSafeLine API Token%s : 请检查配置文件中的 %sSafeLine.ApiToken%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) + logger.Warning.Printf("No %sSafeLine API token%s set: please check the %sSafeLine.ApiToken%s parameter", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) return true } return false @@ -36,32 +36,32 @@ func (safeLine SafeLine) Verify() bool { NoLoginAuthTokenResp, NoLoginStatusCode, NoLoginErr := utils.AuthSafeLine(*safeLine.Host.Url()) if NoLoginErr != nil { - logger.Error.Printf("请求服务端时发生错误: %s%s%s", logger.Red, NoLoginErr.Error(), logger.Reset) + logger.Error.Printf("Error requesting server: %s%s%s", logger.Red, NoLoginErr.Error(), logger.Reset) return true } LoginAuthTokenResp, LoginStatusCode, LoginErr := utils.VerifyAuthToken(*safeLine.Host.Url(), safeLine.ApiToken.String()) if LoginErr != nil { - logger.Error.Printf("验证 %sSafeLine API Token%s 时发生错误: %s%s%s", logger.Cyan, logger.Reset, logger.Red, LoginErr.Error(), logger.Reset) + logger.Error.Printf("Error validating %sSafeLine API token%s: %s%s%s", logger.Cyan, logger.Reset, logger.Red, LoginErr.Error(), logger.Reset) return true } if !(NoLoginAuthTokenResp.Err == "login-required" && NoLoginStatusCode == 401) { - logger.Warning.Printf("服务端接口 %s/open/auth/token%s 请求有误: 请检查配置文件中的 %sSafeLine.Host%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) + logger.Warning.Printf("Server endpoint %s/open/auth/token%s returned error: please check the %sSafeLine.Host%s configuration", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) return true } if LoginAuthTokenResp.Err == "login-required" && LoginStatusCode == 401 { - logger.Warning.Printf("%sSafeLine API Token%s 有误: 请检查后重试", logger.Cyan, logger.Reset) + logger.Warning.Printf("%sSafeLine API token%s is invalid: please check and retry", logger.Cyan, logger.Reset) return true } - logger.Success.Printf("%sSafeLine%s 相关配置检验完成!", logger.Cyan, logger.Reset) + logger.Success.Printf("%sSafeLine%s configuration check completed!", logger.Cyan, logger.Reset) return false } func (apiToken ApiToken) VerifyCommand() bool { if apiToken.String() == "" { - logger.Warning.Printf("未设置 %sSafeLine API Token%s : 请检查命令中的 %s-t%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) + logger.Warning.Printf("No %sSafeLine API token%s set: please check the %s-t%s command-line argument", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) return true } return false @@ -76,25 +76,25 @@ func (safeLine SafeLine) VerifyCommand() bool { NoLoginAuthTokenResp, NoLoginStatusCode, NoLoginErr := utils.AuthSafeLine(*safeLine.Host.Url()) if NoLoginErr != nil { - logger.Error.Printf("请求服务端时发生错误: %s%s%s", logger.Red, NoLoginErr.Error(), logger.Reset) + logger.Error.Printf("Error requesting server: %s%s%s", logger.Red, NoLoginErr.Error(), logger.Reset) return true } LoginAuthTokenResp, LoginStatusCode, LoginErr := utils.VerifyAuthToken(*safeLine.Host.Url(), safeLine.ApiToken.String()) if LoginErr != nil { - logger.Error.Printf("验证 %sSafeLine API Token%s 时发生错误: %s%s%s", logger.Cyan, logger.Reset, logger.Red, LoginErr.Error(), logger.Reset) + logger.Error.Printf("Error validating %sSafeLine API token%s: %s%s%s", logger.Cyan, logger.Reset, logger.Red, LoginErr.Error(), logger.Reset) return true } if !(NoLoginAuthTokenResp.Err == "login-required" && NoLoginStatusCode == 401) { - logger.Warning.Printf("服务端接口 %s/open/auth/token%s 请求有误: 请检查命令中的 %s-h%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) + logger.Warning.Printf("Server endpoint %s/open/auth/token%s returned error: please check the %s-h%s command-line argument", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset) return true } if LoginAuthTokenResp.Err == "login-required" && LoginStatusCode == 401 { - logger.Warning.Printf("%sSafeLine API Token%s 有误: 请检查后重试", logger.Cyan, logger.Reset) + logger.Warning.Printf("%sSafeLine API token%s is invalid: please check and retry", logger.Cyan, logger.Reset) return true } - logger.Success.Printf("%sSafeLine%s 相关配置检验完成!", logger.Cyan, logger.Reset) + logger.Success.Printf("%sSafeLine%s configuration check completed!", logger.Cyan, logger.Reset) return false } diff --git a/pkg/moudle/chooseDNSProvider.go b/pkg/moudle/chooseDNSProvider.go index 5c96c43..a610c9b 100644 --- a/pkg/moudle/chooseDNSProvider.go +++ b/pkg/moudle/chooseDNSProvider.go @@ -22,5 +22,5 @@ func ChooseDNSProvider(config config.DNSProviderConfig) (challenge.Provider, err } else if config.DNSProvider == "Dode" { return config.Dode.Provider() } - return nil, errors.New("未正确设置 DNS 服务提供商") + return nil, errors.New("DNS provider not configured correctly") } diff --git a/pkg/services/ApplyCert.go b/pkg/services/ApplyCert.go index 1694acd..00bea50 100644 --- a/pkg/services/ApplyCert.go +++ b/pkg/services/ApplyCert.go @@ -34,7 +34,7 @@ func (u *MyUser) GetPrivateKey() crypto.PrivateKey { func ApplyCert(domains []string, email, dir string, provider challenge.Provider) bool { privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { - logger.Error.Printf("申请 %s%s%s 证书时发生错误: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) + logger.Error.Printf("Error requesting certificate for %s%s%s: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) return true } myUser := MyUser{ @@ -45,18 +45,18 @@ func ApplyCert(domains []string, email, dir string, provider challenge.Provider) config.Certificate.KeyType = certcrypto.RSA2048 client, err := lego.NewClient(config) if err != nil { - logger.Error.Printf("申请 %s%s%s 证书时发生错误: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) + logger.Error.Printf("Error requesting certificate for %s%s%s: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) return true } err = client.Challenge.SetDNS01Provider(provider) if err != nil { - logger.Error.Printf("申请 %s%s%s 证书时发生错误: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) + logger.Error.Printf("Error requesting certificate for %s%s%s: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) return true } reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true}) if err != nil { - logger.Error.Printf("申请 %s%s%s 证书时发生错误: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) + logger.Error.Printf("Error requesting certificate for %s%s%s: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) return true } myUser.Registration = reg @@ -66,17 +66,17 @@ func ApplyCert(domains []string, email, dir string, provider challenge.Provider) } certificates, err := client.Certificate.Obtain(request) if err != nil { - logger.Error.Printf("申请 %s%s%s 证书时发生错误: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) + logger.Error.Printf("Error requesting certificate for %s%s%s: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) return true } err = os.WriteFile(filepath.Join(dir, domains[0]+".crt"), certificates.Certificate, os.ModePerm) if err != nil { - logger.Error.Printf("保存 %s%s%s 证书时发生错误: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) + logger.Error.Printf("Error saving certificate for %s%s%s: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) return true } err = os.WriteFile(filepath.Join(dir, domains[0]+".key"), certificates.PrivateKey, os.ModePerm) if err != nil { - logger.Error.Printf("保存 %s%s%s 证书密钥时发生错误: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) + logger.Error.Printf("Error saving certificate key for %s%s%s: %s%s%s", logger.Cyan, domains, logger.Reset, logger.Red, err, logger.Reset) return true } return false diff --git a/pkg/utils/List.go b/pkg/utils/List.go index fe41a5c..26653e3 100644 --- a/pkg/utils/List.go +++ b/pkg/utils/List.go @@ -14,7 +14,7 @@ func GetList(url *safeLineApi.URL, token string) safeLineApi.Nodes { } resp, err := Request(LIST, url.SSLCertUrl(), nil, header) if err != nil { - logger.Error.Printf("请求接口 %s/api/open/cert%s 时发生错误: %s%s%s", logger.Cyan, logger.Reset, logger.Red, err, logger.Reset) + logger.Error.Printf("Error requesting endpoint %s/api/open/cert%s: %s%s%s", logger.Cyan, logger.Reset, logger.Red, err, logger.Reset) os.Exit(0) } defer resp.Body.Close() diff --git a/pkg/utils/Upsert.go b/pkg/utils/Upsert.go index 285b825..2b982f2 100644 --- a/pkg/utils/Upsert.go +++ b/pkg/utils/Upsert.go @@ -14,7 +14,7 @@ func Upsert(url *safeLineApi.URL, token string, body io.Reader) safeLineApi.Upse } resp, err := Request(UPSERT, url.SSLCertUrl(), body, header) if err != nil { - logger.Error.Printf("更新证书时发生错误: %s%s%s", logger.Red, err, logger.Reset) + logger.Error.Printf("Error updating certificate: %s%s%s", logger.Red, err, logger.Reset) return safeLineApi.UpsertResp{} } defer resp.Body.Close()