上传证书返回sha256、修改工作流上传节点支持使用本地证书、修改证书续签逻辑新增比对证书域名、修复ssh部署不填写执行前后命令就会报错的bug

pull/79/head^2
zhangchenhao 2025-05-10 15:38:06 +08:00
parent 2fe8b6475f
commit 5e53e5db8c
6 changed files with 135 additions and 77 deletions

View File

@ -50,12 +50,12 @@ func UploadCert(c *gin.Context) {
public.FailMsg(c, "类型不能为空")
return
}
err = cert.UploadCert(form.Key, form.Cert)
sha256, err := cert.UploadCert(form.Key, form.Cert)
if err != nil {
public.FailMsg(c, err.Error())
return
}
public.SuccessMsg(c, "添加成功")
public.SuccessData(c, sha256, 0)
return
}

View File

@ -84,6 +84,10 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
default:
return nil, fmt.Errorf("参数错误provider_id")
}
domainArr := strings.Split(domains, ",")
for i := range domainArr {
domainArr[i] = strings.TrimSpace(domainArr[i])
}
// 获取上次申请的证书
runId, ok := cfg["_runId"].(string)
@ -114,11 +118,17 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
var maxDays float64
var maxItem map[string]any
for i := range certs {
if !public.ContainsAllIgnoreBRepeats(strings.Split(certs[i]["domains"].(string), ","), domainArr) {
continue
}
endTimeStr, ok := certs[i]["end_time"].(string)
if !ok {
continue
}
endTime, _ := time.Parse(layout, endTimeStr)
endTime, err := time.Parse(layout, endTimeStr)
if err != nil {
continue
}
diff := endTime.Sub(time.Now()).Hours() / 24
if diff > maxDays {
maxDays = diff
@ -134,7 +144,7 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
if int(maxDays) > cfgEnd {
// 证书未过期,直接返回
logger.Debug(fmt.Sprintf("上次证书申请成功,剩余天数:%d 大于%d天已跳过申请复用此证书", int(maxDays), cfgEnd))
logger.Debug(fmt.Sprintf("上次证书申请成功,域名:%s,剩余天数:%d 大于%d天已跳过申请复用此证书", certObj["domains"], int(maxDays), cfgEnd))
return map[string]any{
"cert": certObj["cert"],
"key": certObj["key"],
@ -218,7 +228,7 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
// fmt.Println(strings.Split(domains, ","))
request := certificate.ObtainRequest{
Domains: strings.Split(domains, ","),
Domains: domainArr,
Bundle: true,
}
certObj, err := client.Certificate.Obtain(request)
@ -237,7 +247,7 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
"issuerCert": issuerCertStr,
}
err = cert.SaveCert("workflow", keyStr, certStr, issuerCertStr, runId)
_, err = cert.SaveCert("workflow", keyStr, certStr, issuerCertStr, runId)
if err != nil {
return nil, err
}

View File

@ -104,22 +104,22 @@ func AddCert(source, key, cert, issuer, issuerCert, domains, sha256, historyId,
return nil
}
func SaveCert(source, key, cert, issuerCert, historyId string) error {
func SaveCert(source, key, cert, issuerCert, historyId string) (string, error) {
if err := public.ValidateSSLCertificate(cert, key); err != nil {
return err
return "", err
}
certObj, err := public.ParseCertificate([]byte(cert))
if err != nil {
return fmt.Errorf("解析证书失败: %v", err)
return "", fmt.Errorf("解析证书失败: %v", err)
}
// SHA256
sha256, err := public.GetSHA256(cert)
if err != nil {
return fmt.Errorf("获取 SHA256 失败: %v", err)
return "", fmt.Errorf("获取 SHA256 失败: %v", err)
}
if d, _ := GetCert(sha256); d != nil {
return nil
return sha256, nil
}
domainSet := make(map[string]bool)
@ -152,17 +152,17 @@ func SaveCert(source, key, cert, issuerCert, historyId string) error {
err = AddCert(source, key, cert, caName, issuerCert, domainList, sha256, historyId, startTime, endTime, endDay)
if err != nil {
return fmt.Errorf("保存证书失败: %v", err)
return "", fmt.Errorf("保存证书失败: %v", err)
}
return nil
return sha256, nil
}
func UploadCert(key, cert string) error {
err := SaveCert("upload", key, cert, "", "")
func UploadCert(key, cert string) (string, error) {
sha256, err := SaveCert("upload", key, cert, "", "")
if err != nil {
return fmt.Errorf("保存证书失败: %v", err)
return sha256, fmt.Errorf("保存证书失败: %v", err)
}
return nil
return sha256, nil
}
func DelCert(id string) error {

View File

@ -133,11 +133,11 @@ func DeploySSH(cfg map[string]any) error {
}
beforeCmd, ok := cfg["beforeCmd"].(string)
if !ok {
return fmt.Errorf("参数错误beforeCmd")
beforeCmd = ""
}
afterCmd, ok := cfg["afterCmd"].(string)
if !ok {
return fmt.Errorf("参数错误afterCmd")
afterCmd = ""
}
providerData, err := access.GetAccess(providerID)
if err != nil {

View File

@ -8,6 +8,7 @@ import (
"ALLinSSL/backend/public"
"errors"
"fmt"
"strconv"
)
// var executors map[string]func(map[string]any) (any, error)
@ -67,7 +68,8 @@ func deploy(params map[string]any) (any, error) {
func upload(params map[string]any) (any, error) {
logger := params["logger"].(*public.Logger)
logger.Info("=============上传证书=============")
// 判断证书id走本地还是走旧上传应在之后的迭代中移除旧代码
if params["cert_id"] == nil {
keyStr, ok := params["key"].(string)
if !ok {
logger.Error("上传的密钥有误")
@ -80,7 +82,7 @@ func upload(params map[string]any) (any, error) {
logger.Info("=============上传失败=============")
return nil, errors.New("上传的证书有误")
}
err := cert.UploadCert(keyStr, certStr)
_, err := cert.UploadCert(keyStr, certStr)
if err != nil {
logger.Error(err.Error())
logger.Info("=============上传失败=============")
@ -89,6 +91,31 @@ func upload(params map[string]any) (any, error) {
logger.Info("=============上传成功=============")
return params, nil
} else {
certId := ""
switch v := params["cert_id"].(type) {
case float64:
certId = strconv.Itoa(int(v))
case string:
certId = v
default:
logger.Info("=============上传证书获取失败=============")
return nil, errors.New("证书 ID 类型错误")
}
certObj, err := cert.GetCert(certId)
if err != nil {
logger.Error(err.Error())
logger.Info("=============上传证书获取失败=============")
return nil, err
}
if certObj == nil {
logger.Error("证书不存在")
logger.Info("=============上传证书获取失败=============")
return nil, errors.New("证书不存在")
}
logger.Debug(fmt.Sprintf("证书 ID: %s", certId))
return certObj, nil
}
}
func notify(params map[string]any) (any, error) {

View File

@ -179,3 +179,24 @@ func GetPublicIP() (string, error) {
return string(body), nil
}
func ContainsAllIgnoreBRepeats(a, b []string) bool {
// 构建 A 的集合
setA := make(map[string]struct{})
for _, item := range a {
setA[item] = struct{}{}
}
// 遍历 B 的唯一元素,判断是否在 A 中
seen := make(map[string]struct{})
for _, item := range b {
if _, checked := seen[item]; checked {
continue
}
seen[item] = struct{}{}
if _, ok := setA[item]; !ok {
return false
}
}
return true
}