重构项目
This commit is contained in:
19
internal/Func/ChooseProvider.go
Normal file
19
internal/Func/ChooseProvider.go
Normal file
@ -0,0 +1,19 @@
|
||||
package Func
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/app/logger"
|
||||
"SafelineAPI/internal/class/Acme"
|
||||
|
||||
"github.com/go-acme/lego/v4/challenge"
|
||||
)
|
||||
|
||||
func ChooseProvider(config Acme.Acme) ([]challenge.Provider, bool) {
|
||||
providers, errors := config.DNSProvider.Choose()
|
||||
for _, e := range errors {
|
||||
logger.Error.Println(e)
|
||||
}
|
||||
if len(providers) == 0 {
|
||||
return nil, true
|
||||
}
|
||||
return providers, false
|
||||
}
|
||||
22
internal/Func/UpdateCheck.go
Normal file
22
internal/Func/UpdateCheck.go
Normal file
@ -0,0 +1,22 @@
|
||||
package Func
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/app/SafelineRequest"
|
||||
"SafelineAPI/internal/app/logger"
|
||||
"SafelineAPI/internal/class/config"
|
||||
"SafelineAPI/internal/moudle"
|
||||
"SafelineAPI/pkg/utils"
|
||||
"log"
|
||||
)
|
||||
|
||||
func UpdateCertCheck(conf config.Config) ([]SafelineRequest.Nodes, bool) {
|
||||
certNodes := utils.GetList(conf.Server.Host.Url(), conf.Server.ApiToken.String())
|
||||
certUpsert := moudle.CheckNodes(certNodes, conf.Days)
|
||||
if len(certUpsert) != 0 {
|
||||
log.Printf("本次需要更新证书数量有 %s%d%s 个,现在开始更新...", logger.Yellow, len(certUpsert), logger.Reset)
|
||||
} else {
|
||||
log.Print("本次无需更新证书,即将退出本程序。")
|
||||
return nil, true
|
||||
}
|
||||
return certUpsert, false
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package safeLineApi
|
||||
package SafelineRequest
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
package safeLineApi
|
||||
package SafelineRequest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -20,13 +18,11 @@ type UpsertReq struct {
|
||||
Type int `json:"type"`
|
||||
}
|
||||
|
||||
func (upsertReq *UpsertReq) Create(domains []string, email, dir string, id, Type int) {
|
||||
certificate, _ := os.ReadFile(filepath.Join(dir, domains[0]+".crt"))
|
||||
privateKey, _ := os.ReadFile(filepath.Join(dir, domains[0]+".key"))
|
||||
func (upsertReq *UpsertReq) Create(Certificate, PrivateKey []byte, domains []string, email string, id, Type int) {
|
||||
upsertReq.Acme.Domains = domains
|
||||
upsertReq.Acme.Email = email
|
||||
upsertReq.Manual.Crt = string(certificate)
|
||||
upsertReq.Manual.Key = string(privateKey)
|
||||
upsertReq.Manual.Crt = string(Certificate)
|
||||
upsertReq.Manual.Key = string(PrivateKey)
|
||||
upsertReq.Id = id
|
||||
upsertReq.Type = Type
|
||||
}
|
||||
@ -48,14 +44,14 @@ func (upsertResp *UpsertResp) Unmarshal(data []byte) {
|
||||
|
||||
type ListResp struct {
|
||||
Data struct {
|
||||
Nodes `json:"nodes"`
|
||||
Total int `json:"total"`
|
||||
Nodes []Nodes `json:"nodes"`
|
||||
Total int `json:"total"`
|
||||
} `json:"data"`
|
||||
Err string `json:"err"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
type Nodes []struct {
|
||||
type Nodes struct {
|
||||
Id int `json:"id"`
|
||||
Domains []string `json:"domains"`
|
||||
Issuer string `json:"issuer"`
|
||||
@ -1,4 +1,4 @@
|
||||
package safeLineApi
|
||||
package SafelineRequest
|
||||
|
||||
const (
|
||||
GetTOKEN = "GET"
|
||||
@ -1,10 +1,16 @@
|
||||
package safeLineApi
|
||||
package SafelineRequest
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type URL url.URL
|
||||
|
||||
func (u *URL) String() string {
|
||||
return (*url.URL)(u).String()
|
||||
}
|
||||
|
||||
func (u *URL) SSLCertUrl() string {
|
||||
path := "/api/open/cert"
|
||||
u.Path = path
|
||||
@ -16,3 +22,9 @@ func (u *URL) SSLCertUrlWithParam(id int) string {
|
||||
u.Path = path
|
||||
return (*url.URL)(u).String()
|
||||
}
|
||||
|
||||
func (u *URL) AuthTokenUrl() string {
|
||||
path := "/api/open/auth/token"
|
||||
u.Path = path
|
||||
return (*url.URL)(u).String()
|
||||
}
|
||||
@ -1,91 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/app/logger"
|
||||
"flag"
|
||||
"github.com/go-jose/go-jose/v4/json"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
SafeLine `json:"SafeLine"`
|
||||
ApplyCert `json:"ApplyCert"`
|
||||
}
|
||||
|
||||
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)
|
||||
os.Exit(0)
|
||||
}
|
||||
err = json.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
logger.Error.Printf("配置文件读取失败: %s%s%s", logger.Red, err, logger.Reset)
|
||||
os.Exit(0)
|
||||
}
|
||||
config.Verify()
|
||||
}
|
||||
func (config *Config) Write(path string) {
|
||||
data, _ := json.MarshalIndent(config, "", " ")
|
||||
_ = os.WriteFile(path, data, 0644)
|
||||
}
|
||||
|
||||
func (config *Config) Command() {
|
||||
var hostname, port, apiToken, save, email *string
|
||||
var days *int
|
||||
var DNSProvider *string
|
||||
|
||||
hostname = flag.String("h", "172.22.222.4", "-h <hostname>")
|
||||
port = flag.String("p", "9443", "-p <port>")
|
||||
apiToken = flag.String("t", "", "-t <apiToken>")
|
||||
days = flag.Int("d", 30, "-t <days>")
|
||||
save = flag.String("s", "/tmp/ssl", "-s <save file>")
|
||||
email = flag.String("e", "", "-e <email>")
|
||||
DNSProvider = flag.String("D", "", "-D <DNS Provider> (e.g., TencentCloud, AliCloud, HuaweiCloud, WestCN, RainYun)")
|
||||
kvp := flag.String("kv", "", "-kv <key=value>,<key=value>...")
|
||||
flag.Parse()
|
||||
|
||||
var KVP = make(KVPair)
|
||||
if *kvp != "" {
|
||||
KVP.Set(*kvp)
|
||||
}
|
||||
|
||||
config.SafeLine = SafeLine{
|
||||
Host: Host{
|
||||
HostName: *hostname,
|
||||
Port: *port,
|
||||
},
|
||||
ApiToken: ApiToken(*apiToken),
|
||||
}
|
||||
config.ApplyCert = ApplyCert{
|
||||
Days: *days,
|
||||
SavePath: *save,
|
||||
Email: *email,
|
||||
DNSProviderConfig: DNSProviderConfig{
|
||||
DNSProvider: *DNSProvider,
|
||||
TencentCloud: TencentCloud{
|
||||
SecretID: KVP["SecretID"],
|
||||
SecretKey: KVP["SecretKey"],
|
||||
},
|
||||
AliCloud: AliCloud{
|
||||
AccessKeyId: KVP["AccessKeyId"],
|
||||
AccessKeySecret: KVP["AccessKeySecret"],
|
||||
RAMRole: KVP["RAMRole"],
|
||||
STSToken: KVP["STSToken"],
|
||||
},
|
||||
HuaweiCloud: HuaweiCloud{
|
||||
AccessKeyId: KVP["AccessKeyId"],
|
||||
Region: KVP["Region"],
|
||||
SecretAccessKey: KVP["SecretAccessKey"],
|
||||
},
|
||||
WestCN: WestCN{
|
||||
Username: KVP["Username"],
|
||||
Password: KVP["Password"],
|
||||
},
|
||||
RainYun: RainYun{
|
||||
ApiKey: KVP["ApiKey"],
|
||||
},
|
||||
},
|
||||
}
|
||||
config.VerifyCommand()
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/app/logger"
|
||||
"log"
|
||||
)
|
||||
|
||||
type ApplyCert struct {
|
||||
Days int `json:"Days"`
|
||||
Email string `json:"Email"`
|
||||
SavePath string `json:"SavePath"`
|
||||
DNSProviderConfig `json:"DNSProviderConfig"`
|
||||
}
|
||||
|
||||
func (applyCert *ApplyCert) GetDays() int {
|
||||
return applyCert.Days
|
||||
}
|
||||
|
||||
func (applyCert *ApplyCert) GetEmail() string {
|
||||
return applyCert.Email
|
||||
}
|
||||
|
||||
func (applyCert *ApplyCert) Verify() bool {
|
||||
var flag = false
|
||||
if applyCert.Days == 0 {
|
||||
applyCert.Days = 30
|
||||
}
|
||||
|
||||
if applyCert.SavePath == "" {
|
||||
applyCert.SavePath = "/tmp/ssl"
|
||||
}
|
||||
|
||||
if applyCert.DNSProvider == "" {
|
||||
logger.Warning.Printf("未设置 %sDNS服务提供商%s: 请检查配置文件中的 %sApplyCert.DNSProviderConfig.DNSProvider%s 参数", 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)
|
||||
flag = true
|
||||
}
|
||||
if !flag {
|
||||
log.Printf("%sApplyCert%s 相关配置检验完成!", logger.Cyan, logger.Reset)
|
||||
}
|
||||
return flag
|
||||
}
|
||||
|
||||
func (applyCert *ApplyCert) VerifyCommand() bool {
|
||||
var flag = false
|
||||
if applyCert.Days == 0 {
|
||||
applyCert.Days = 30
|
||||
}
|
||||
|
||||
if applyCert.SavePath == "" {
|
||||
applyCert.SavePath = "/tmp/ssl"
|
||||
}
|
||||
|
||||
if applyCert.DNSProvider == "" {
|
||||
logger.Warning.Printf("未设置 %sDNS服务提供商%s: 请检查命令中的 %s-D%s 参数", 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)
|
||||
flag = true
|
||||
}
|
||||
if !flag {
|
||||
log.Printf("%sApplyCert%s 相关配置检验完成!", logger.Cyan, logger.Reset)
|
||||
}
|
||||
return flag
|
||||
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
package config
|
||||
|
||||
func (config *Config) Default() {
|
||||
a := Config{
|
||||
SafeLine: SafeLine{
|
||||
Host: Host{
|
||||
HostName: "192.168.1.4",
|
||||
Port: "1443",
|
||||
},
|
||||
ApiToken: "xxx",
|
||||
},
|
||||
ApplyCert: ApplyCert{
|
||||
Days: 30,
|
||||
Email: "xxx",
|
||||
SavePath: "/tmp/ssl",
|
||||
DNSProviderConfig: DNSProviderConfig{
|
||||
DNSProvider: "xxx",
|
||||
TencentCloud: TencentCloud{
|
||||
SecretID: "xxx",
|
||||
SecretKey: "xxx",
|
||||
},
|
||||
AliCloud: AliCloud{
|
||||
AccessKeyId: "xxx",
|
||||
AccessKeySecret: "xxx",
|
||||
RAMRole: "xxx(可选)",
|
||||
STSToken: "xxx(可选)",
|
||||
},
|
||||
HuaweiCloud: HuaweiCloud{
|
||||
AccessKeyId: "xxx",
|
||||
Region: "xxx",
|
||||
SecretAccessKey: "xxx",
|
||||
},
|
||||
WestCN: WestCN{
|
||||
Username: "xxx",
|
||||
Password: "xxx",
|
||||
},
|
||||
RainYun: RainYun{
|
||||
ApiKey: "xxx",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
a.Write("./config.json")
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/app/logger"
|
||||
"SafelineAPI/internal/app/safeLineApi"
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type Host struct {
|
||||
HostName string `json:"HostName"`
|
||||
Port string `json:"Port"`
|
||||
}
|
||||
|
||||
func (host Host) String() string {
|
||||
if host.Port == "" {
|
||||
return host.HostName
|
||||
}
|
||||
return host.HostName + ":" + host.Port
|
||||
}
|
||||
|
||||
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)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (host Host) VerifyCommand() bool {
|
||||
if host.HostName == "" {
|
||||
logger.Warning.Printf("未设置 %s主机名称%s: 请检查命令中的 %s-h%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (host Host) Url() *safeLineApi.URL {
|
||||
var u *url.URL
|
||||
if host.Port == "" {
|
||||
u, _ = url.Parse(fmt.Sprintf("https://%s", host.HostName))
|
||||
} else {
|
||||
u, _ = url.Parse(fmt.Sprintf("https://%s:%s", host.HostName, host.Port))
|
||||
}
|
||||
return (*safeLineApi.URL)(u)
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func (config *Config) Verify() {
|
||||
a := config.SafeLine.Verify()
|
||||
b := config.ApplyCert.Verify()
|
||||
if a || b {
|
||||
log.Printf("配置检查完毕,请检查相关配置后重新运行!")
|
||||
os.Exit(0)
|
||||
}
|
||||
log.Printf("配置检查完毕,即将开始更新证书!")
|
||||
}
|
||||
|
||||
func (config *Config) VerifyCommand() {
|
||||
a := config.SafeLine.VerifyCommand()
|
||||
b := config.ApplyCert.VerifyCommand()
|
||||
if a || b {
|
||||
log.Printf("配置检查完毕,请检查相关配置后重新运行!")
|
||||
os.Exit(0)
|
||||
}
|
||||
log.Printf("配置检查完毕,即将开始更新证书!")
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type KVPair map[string]string
|
||||
|
||||
func (kvp *KVPair) Set(str string) {
|
||||
kvps := strings.Split(str, ",")
|
||||
for _, i := range kvps {
|
||||
kv := strings.SplitN(i, "=", 2)
|
||||
(*kvp)[kv[0]] = kv[1]
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
package safeLineApi
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func (u *URL) AuthTokenUrl() string {
|
||||
path := "/api/open/auth/token"
|
||||
u.Path = path
|
||||
return (*url.URL)(u).String()
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
package safeLineApi
|
||||
|
||||
import "net/url"
|
||||
|
||||
type URL url.URL
|
||||
|
||||
func (u *URL) String() string {
|
||||
return (*url.URL)(u).String()
|
||||
}
|
||||
33
internal/class/Acme/Method.go
Normal file
33
internal/class/Acme/Method.go
Normal file
@ -0,0 +1,33 @@
|
||||
package Acme
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/app/logger"
|
||||
"log"
|
||||
)
|
||||
|
||||
func (acme *Acme) Verify() bool {
|
||||
var flag = false
|
||||
|
||||
if acme.Email == "" {
|
||||
logger.Warning.Printf("未设置 %s证书申请邮箱%s: 请检查配置文件中的 %sApplyCert.Email%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
|
||||
flag = true
|
||||
}
|
||||
if !flag {
|
||||
log.Printf("%sApplyCert%s 相关配置检验完成!", logger.Cyan, logger.Reset)
|
||||
}
|
||||
return flag
|
||||
}
|
||||
|
||||
func (acme *Acme) VerifyCommand() bool {
|
||||
var flag = false
|
||||
|
||||
if acme.Email == "" {
|
||||
logger.Warning.Printf("未设置 %s证书申请邮箱%s: 请检查命令中的 %s-e%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
|
||||
flag = true
|
||||
}
|
||||
if !flag {
|
||||
log.Printf("%sApplyCert%s 相关配置检验完成!", logger.Cyan, logger.Reset)
|
||||
}
|
||||
return flag
|
||||
|
||||
}
|
||||
10
internal/class/Acme/Object.go
Normal file
10
internal/class/Acme/Object.go
Normal file
@ -0,0 +1,10 @@
|
||||
package Acme
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/class/DNSProvider"
|
||||
)
|
||||
|
||||
type Acme struct {
|
||||
Email string `json:"Email"`
|
||||
DNSProvider DNSProvider.DNSProvider `json:"DNSProvider"`
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package config
|
||||
package DNSProvider
|
||||
|
||||
import (
|
||||
"github.com/go-acme/lego/v4/challenge"
|
||||
@ -1,14 +1,4 @@
|
||||
package config
|
||||
|
||||
type DNSProviderConfig struct {
|
||||
DNSProvider string `json:"DNSProvider"`
|
||||
TencentCloud `json:"TencentCloud,omitempty"`
|
||||
AliCloud `json:"AliCloud,omitempty"`
|
||||
HuaweiCloud `json:"HuaweiCloud,omitempty"`
|
||||
WestCN `json:"WestCN,omitempty"`
|
||||
RainYun `json:"RainYun,omitempty"`
|
||||
Dode `json:"Dode,omitempty"`
|
||||
}
|
||||
package DNSProvider
|
||||
|
||||
type TencentCloud struct {
|
||||
SecretID string `json:"SecretId,omitempty"`
|
||||
43
internal/class/DNSProvider/Objects.go
Normal file
43
internal/class/DNSProvider/Objects.go
Normal file
@ -0,0 +1,43 @@
|
||||
package DNSProvider
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/go-acme/lego/v4/challenge"
|
||||
)
|
||||
|
||||
type DNSProvider struct {
|
||||
TencentCloud TencentCloud `json:"TencentCloud,omitempty"`
|
||||
AliCloud AliCloud `json:"AliCloud,omitempty"`
|
||||
HuaweiCloud HuaweiCloud `json:"HuaweiCloud,omitempty"`
|
||||
WestCN WestCN `json:"WestCN,omitempty"`
|
||||
RainYun RainYun `json:"RainYun,omitempty"`
|
||||
Dode Dode `json:"Dode,omitempty"`
|
||||
}
|
||||
|
||||
func (dnsProvider *DNSProvider) Choose() ([]challenge.Provider, []error) {
|
||||
|
||||
var Providers []challenge.Provider
|
||||
var Errors []error
|
||||
v := reflect.ValueOf(dnsProvider).Elem()
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
field := v.Field(i)
|
||||
if field.Kind() == reflect.Struct {
|
||||
for ii := 0; ii < field.NumField(); ii++ {
|
||||
if field.Field(ii).String() != "" {
|
||||
method, _ := field.Type().MethodByName("Provider")
|
||||
results := method.Func.Call([]reflect.Value{field})
|
||||
err, _ := results[1].Interface().(error)
|
||||
if err != nil {
|
||||
Errors = append(Errors, err)
|
||||
} else {
|
||||
Providers = append(Providers, results[0].Interface().(challenge.Provider))
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Providers, Errors
|
||||
}
|
||||
9
internal/class/DNSProvider/SubObject.go
Normal file
9
internal/class/DNSProvider/SubObject.go
Normal file
@ -0,0 +1,9 @@
|
||||
package DNSProvider
|
||||
|
||||
import "github.com/go-acme/lego/v4/challenge"
|
||||
|
||||
type Result struct {
|
||||
Provider challenge.Provider
|
||||
Error error
|
||||
}
|
||||
type Msg map[string]Result
|
||||
17
internal/class/MyUser/Method.go
Normal file
17
internal/class/MyUser/Method.go
Normal file
@ -0,0 +1,17 @@
|
||||
package MyUser
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
)
|
||||
|
||||
func (myUser *MyUser) GetEmail() string {
|
||||
return myUser.Email
|
||||
}
|
||||
func (myUser *MyUser) GetRegistration() *registration.Resource {
|
||||
return myUser.Registration
|
||||
}
|
||||
func (myUser *MyUser) GetPrivateKey() crypto.PrivateKey {
|
||||
return myUser.Key
|
||||
}
|
||||
13
internal/class/MyUser/Object.go
Normal file
13
internal/class/MyUser/Object.go
Normal file
@ -0,0 +1,13 @@
|
||||
package MyUser
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
)
|
||||
|
||||
type MyUser struct {
|
||||
Email string
|
||||
Registration *registration.Resource
|
||||
Key crypto.PrivateKey
|
||||
}
|
||||
@ -1,16 +1,13 @@
|
||||
package config
|
||||
package Safeline
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/app/SafelineRequest"
|
||||
"SafelineAPI/internal/app/logger"
|
||||
"SafelineAPI/pkg/utils"
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type SafeLine struct {
|
||||
Host `json:"Host"`
|
||||
ApiToken `json:"ApiToken"`
|
||||
}
|
||||
type ApiToken string
|
||||
|
||||
func (apiToken ApiToken) GetApiToken() (string, string) {
|
||||
return "X-SLCE-API-TOKEN", apiToken.String()
|
||||
}
|
||||
@ -98,3 +95,25 @@ func (safeLine SafeLine) VerifyCommand() bool {
|
||||
logger.Success.Printf("%sSafeLine%s 相关配置检验完成!", logger.Cyan, logger.Reset)
|
||||
return false
|
||||
}
|
||||
|
||||
func (host Host) Verify() bool {
|
||||
if host == "" {
|
||||
logger.Warning.Printf("未设置 %s服务器主机%s: 请检查配置文件中的 %sSafeLine.Host%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (host Host) VerifyCommand() bool {
|
||||
if host == "" {
|
||||
logger.Warning.Printf("未设置 %s主机名称%s: 请检查命令中的 %s-h%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (host Host) Url() *SafelineRequest.URL {
|
||||
var u *url.URL
|
||||
u, _ = url.Parse(fmt.Sprintf("https://%s", host))
|
||||
return (*SafelineRequest.URL)(u)
|
||||
}
|
||||
9
internal/class/Safeline/Object.go
Normal file
9
internal/class/Safeline/Object.go
Normal file
@ -0,0 +1,9 @@
|
||||
package Safeline
|
||||
|
||||
type SafeLine struct {
|
||||
Host Host `json:"Host"`
|
||||
ApiToken ApiToken `json:"ApiToken"`
|
||||
}
|
||||
|
||||
type Host string
|
||||
type ApiToken string
|
||||
106
internal/class/config/Method.go
Normal file
106
internal/class/config/Method.go
Normal file
@ -0,0 +1,106 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/app/logger"
|
||||
"SafelineAPI/internal/class/Acme"
|
||||
"SafelineAPI/internal/class/DNSProvider"
|
||||
"SafelineAPI/internal/class/Safeline"
|
||||
"SafelineAPI/pkg/utils"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
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)
|
||||
os.Exit(0)
|
||||
}
|
||||
err = json.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
logger.Error.Printf("配置文件读取失败: %s%s%s", logger.Red, err, logger.Reset)
|
||||
os.Exit(0)
|
||||
}
|
||||
config.Verify()
|
||||
}
|
||||
func (config *Config) Write(path string) {
|
||||
data, _ := json.MarshalIndent(config, "", " ")
|
||||
_ = os.WriteFile(path, data, 0644)
|
||||
}
|
||||
|
||||
func (config *Config) Command() {
|
||||
var host, apiToken, email *string
|
||||
var days, concurrency *int
|
||||
|
||||
host = flag.String("h", "172.22.222.4:1443", "-h <host>")
|
||||
apiToken = flag.String("t", "", "-t <apiToken>")
|
||||
days = flag.Int("d", 30, "-t <days>")
|
||||
concurrency = flag.Int("c", 3, "-c <concurrency>")
|
||||
email = flag.String("e", "", "-e <email>")
|
||||
kvp := flag.String("kv", "", "-kv <key=value>,<key=value>...")
|
||||
flag.Parse()
|
||||
|
||||
var KVP = make(utils.KVPair)
|
||||
if *kvp != "" {
|
||||
KVP.Set(*kvp)
|
||||
}
|
||||
|
||||
config.Days = *days
|
||||
config.Concurrency = *concurrency
|
||||
config.Server = Safeline.SafeLine{
|
||||
Host: Safeline.Host(*host),
|
||||
ApiToken: Safeline.ApiToken(*apiToken),
|
||||
}
|
||||
config.Acme = Acme.Acme{
|
||||
Email: *email,
|
||||
DNSProvider: DNSProvider.DNSProvider{
|
||||
TencentCloud: DNSProvider.TencentCloud{
|
||||
SecretID: KVP["SecretID"],
|
||||
SecretKey: KVP["SecretKey"],
|
||||
},
|
||||
AliCloud: DNSProvider.AliCloud{
|
||||
AccessKeyId: KVP["AccessKeyId"],
|
||||
AccessKeySecret: KVP["AccessKeySecret"],
|
||||
RAMRole: KVP["RAMRole"],
|
||||
STSToken: KVP["STSToken"],
|
||||
},
|
||||
HuaweiCloud: DNSProvider.HuaweiCloud{
|
||||
AccessKeyId: KVP["AccessKeyId"],
|
||||
Region: KVP["Region"],
|
||||
SecretAccessKey: KVP["SecretAccessKey"],
|
||||
},
|
||||
WestCN: DNSProvider.WestCN{
|
||||
Username: KVP["Username"],
|
||||
Password: KVP["Password"],
|
||||
},
|
||||
RainYun: DNSProvider.RainYun{
|
||||
ApiKey: KVP["ApiKey"],
|
||||
},
|
||||
Dode: DNSProvider.Dode{
|
||||
Token: KVP["Token"],
|
||||
},
|
||||
},
|
||||
}
|
||||
config.VerifyCommand()
|
||||
}
|
||||
func (config *Config) Verify() {
|
||||
a := config.Server.Verify()
|
||||
b := config.Acme.Verify()
|
||||
if a || b {
|
||||
log.Printf("配置检查完毕,请检查相关配置后重新运行!")
|
||||
os.Exit(0)
|
||||
}
|
||||
log.Printf("配置检查完毕,即将开始更新证书!")
|
||||
}
|
||||
|
||||
func (config *Config) VerifyCommand() {
|
||||
a := config.Server.VerifyCommand()
|
||||
b := config.Acme.VerifyCommand()
|
||||
if a || b {
|
||||
log.Printf("配置检查完毕,请检查相关配置后重新运行!")
|
||||
os.Exit(0)
|
||||
}
|
||||
log.Printf("配置检查完毕,即将开始更新证书!")
|
||||
}
|
||||
13
internal/class/config/Object.go
Normal file
13
internal/class/config/Object.go
Normal file
@ -0,0 +1,13 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/class/Acme"
|
||||
"SafelineAPI/internal/class/Safeline"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Concurrency int `json:"Concurrency"`
|
||||
Days int `json:"Days"`
|
||||
Server Safeline.SafeLine `json:"Server"`
|
||||
Acme Acme.Acme `json:"Acme"`
|
||||
}
|
||||
49
internal/class/config/default.go
Normal file
49
internal/class/config/default.go
Normal file
@ -0,0 +1,49 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/class/Acme"
|
||||
"SafelineAPI/internal/class/DNSProvider"
|
||||
"SafelineAPI/internal/class/Safeline"
|
||||
)
|
||||
|
||||
func (config *Config) Default() {
|
||||
a := Config{
|
||||
Concurrency: 3,
|
||||
Days: 15,
|
||||
Server: Safeline.SafeLine{
|
||||
Host: "192.168.1.4:1443",
|
||||
ApiToken: "xxx",
|
||||
},
|
||||
Acme: Acme.Acme{
|
||||
Email: "xxx",
|
||||
DNSProvider: DNSProvider.DNSProvider{
|
||||
TencentCloud: DNSProvider.TencentCloud{
|
||||
SecretID: "xxx",
|
||||
SecretKey: "xxx",
|
||||
},
|
||||
AliCloud: DNSProvider.AliCloud{
|
||||
AccessKeyId: "xxx",
|
||||
AccessKeySecret: "xxx",
|
||||
RAMRole: "xxx(可选)",
|
||||
STSToken: "xxx(可选)",
|
||||
},
|
||||
HuaweiCloud: DNSProvider.HuaweiCloud{
|
||||
AccessKeyId: "xxx",
|
||||
Region: "xxx",
|
||||
SecretAccessKey: "xxx",
|
||||
},
|
||||
WestCN: DNSProvider.WestCN{
|
||||
Username: "xxx",
|
||||
Password: "xxx",
|
||||
},
|
||||
RainYun: DNSProvider.RainYun{
|
||||
ApiKey: "xxx",
|
||||
},
|
||||
Dode: DNSProvider.Dode{
|
||||
Token: "xxx",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
a.Write("./config.json")
|
||||
}
|
||||
61
internal/moudle/ApplyCert.go
Normal file
61
internal/moudle/ApplyCert.go
Normal file
@ -0,0 +1,61 @@
|
||||
package moudle
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/app/logger"
|
||||
"SafelineAPI/internal/class/MyUser"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
|
||||
"github.com/go-acme/lego/v4/certcrypto"
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
"github.com/go-acme/lego/v4/challenge"
|
||||
"github.com/go-acme/lego/v4/lego"
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
)
|
||||
|
||||
func ApplyCert(domains []string, email string, provider challenge.Provider) ([]byte, []byte, 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)
|
||||
return nil, nil, true
|
||||
}
|
||||
|
||||
myUser := MyUser.MyUser{
|
||||
Email: email,
|
||||
Key: privateKey,
|
||||
}
|
||||
|
||||
config := lego.NewConfig(&myUser)
|
||||
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)
|
||||
return nil, nil, 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)
|
||||
return nil, nil, 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)
|
||||
return nil, nil, true
|
||||
}
|
||||
|
||||
myUser.Registration = reg
|
||||
request := certificate.ObtainRequest{
|
||||
Domains: domains,
|
||||
Bundle: true,
|
||||
}
|
||||
|
||||
certResource, 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)
|
||||
return nil, nil, true
|
||||
}
|
||||
|
||||
return certResource.Certificate, certResource.PrivateKey, false
|
||||
}
|
||||
23
internal/moudle/UpdateCert.go
Normal file
23
internal/moudle/UpdateCert.go
Normal file
@ -0,0 +1,23 @@
|
||||
package moudle
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/app/SafelineRequest"
|
||||
"SafelineAPI/internal/app/logger"
|
||||
"SafelineAPI/internal/class/config"
|
||||
"SafelineAPI/pkg/utils"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
func UpdateCert(conf config.Config, email string, Certificate, PrivateKey []byte, cert SafelineRequest.Nodes) ([]string, []string) {
|
||||
var upsertReq SafelineRequest.UpsertReq
|
||||
upsertReq.Create(Certificate, PrivateKey, cert.Domains, email, cert.Id, cert.Type)
|
||||
|
||||
body := bytes.NewReader(upsertReq.Marshal())
|
||||
result := utils.Upsert(conf.Server.Host.Url(), conf.Server.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)
|
||||
return nil, cert.Domains
|
||||
}
|
||||
logger.Success.Printf("域名 %s%s%s 证书更新成功!", logger.Cyan, cert.Domains, logger.Reset)
|
||||
return cert.Domains, nil
|
||||
}
|
||||
18
internal/moudle/checkNodes.go
Normal file
18
internal/moudle/checkNodes.go
Normal file
@ -0,0 +1,18 @@
|
||||
package moudle
|
||||
|
||||
import (
|
||||
"SafelineAPI/internal/app/SafelineRequest"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CheckNodes(nodes []SafelineRequest.Nodes, n int) []SafelineRequest.Nodes {
|
||||
var need []SafelineRequest.Nodes
|
||||
date := time.Now()
|
||||
for _, node := range nodes {
|
||||
days := int(node.ValidBefore.Sub(date).Hours() / 24)
|
||||
if days <= n {
|
||||
need = append(need, node)
|
||||
}
|
||||
}
|
||||
return need
|
||||
}
|
||||
18
internal/moudle/chooseDNSProvider.go
Normal file
18
internal/moudle/chooseDNSProvider.go
Normal file
@ -0,0 +1,18 @@
|
||||
package moudle
|
||||
|
||||
//func ChooseDNSProvider(config DNSProvider.Config) (challenge.Provider, error) {
|
||||
// if config.ProviderName == "TencentCloud" {
|
||||
// return config.TencentCloud.Provider()
|
||||
// } else if config.ProviderName == "AliCloud" {
|
||||
// return config.AliCloud.Provider()
|
||||
// } else if config.ProviderName == "HuaweiCloud" {
|
||||
// return config.HuaweiCloud.Provider()
|
||||
// } else if config.ProviderName == "WestCN" {
|
||||
// return config.WestCN.Provider()
|
||||
// } else if config.ProviderName == "RainYun" {
|
||||
// return config.RainYun.Provider()
|
||||
// } else if config.ProviderName == "Dode" {
|
||||
// return config.Dode.Provider()
|
||||
// }
|
||||
// return nil, errors.New("未正确设置 DNS 服务提供商")
|
||||
//}
|
||||
Reference in New Issue
Block a user