mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-07 21:19:51 +00:00
fix: ari double renewal error
This commit is contained in:
parent
970a1f0f79
commit
46b4ff73c9
@ -26,13 +26,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ApplyResult struct {
|
type ApplyResult struct {
|
||||||
|
CSR string
|
||||||
FullChainCertificate string
|
FullChainCertificate string
|
||||||
IssuerCertificate string
|
IssuerCertificate string
|
||||||
PrivateKey string
|
PrivateKey string
|
||||||
ACMEAccountUrl string
|
ACMEAccountUrl string
|
||||||
ACMECertUrl string
|
ACMECertUrl string
|
||||||
ACMECertStableUrl string
|
ACMECertStableUrl string
|
||||||
CSR string
|
ARIReplaced bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Applicant interface {
|
type Applicant interface {
|
||||||
@ -109,7 +110,7 @@ func NewWithWorkflowNode(config ApplicantWithWorkflowNodeConfig) (Applicant, err
|
|||||||
|
|
||||||
certRepo := repository.NewCertificateRepository()
|
certRepo := repository.NewCertificateRepository()
|
||||||
lastCertificate, _ := certRepo.GetByWorkflowNodeId(context.Background(), config.Node.Id)
|
lastCertificate, _ := certRepo.GetByWorkflowNodeId(context.Background(), config.Node.Id)
|
||||||
if lastCertificate != nil {
|
if lastCertificate != nil && !lastCertificate.ACMERenewed {
|
||||||
newCertSan := slices.Clone(options.Domains)
|
newCertSan := slices.Clone(options.Domains)
|
||||||
oldCertSan := strings.Split(lastCertificate.SubjectAltNames, ";")
|
oldCertSan := strings.Split(lastCertificate.SubjectAltNames, ";")
|
||||||
slices.Sort(newCertSan)
|
slices.Sort(newCertSan)
|
||||||
@ -119,8 +120,8 @@ func NewWithWorkflowNode(config ApplicantWithWorkflowNodeConfig) (Applicant, err
|
|||||||
lastCertX509, _ := certcrypto.ParsePEMCertificate([]byte(lastCertificate.Certificate))
|
lastCertX509, _ := certcrypto.ParsePEMCertificate([]byte(lastCertificate.Certificate))
|
||||||
if lastCertX509 != nil {
|
if lastCertX509 != nil {
|
||||||
replacedARICertId, _ := certificate.MakeARICertID(lastCertX509)
|
replacedARICertId, _ := certificate.MakeARICertID(lastCertX509)
|
||||||
options.ReplacedARIAcct = lastCertificate.ACMEAccountUrl
|
options.ARIReplaceAcct = lastCertificate.ACMEAccountUrl
|
||||||
options.ReplacedARICert = replacedARICertId
|
options.ARIReplaceCert = replacedARICertId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -235,22 +236,24 @@ func applyUseLego(legoProvider challenge.Provider, options *applicantProviderOpt
|
|||||||
Domains: options.Domains,
|
Domains: options.Domains,
|
||||||
Bundle: true,
|
Bundle: true,
|
||||||
}
|
}
|
||||||
if options.ReplacedARIAcct == user.Registration.URI {
|
if options.ARIReplaceAcct == user.Registration.URI {
|
||||||
certRequest.ReplacesCertID = options.ReplacedARICert
|
certRequest.ReplacesCertID = options.ARIReplaceCert
|
||||||
}
|
}
|
||||||
|
|
||||||
certResource, err := client.Certificate.Obtain(certRequest)
|
certResource, err := client.Certificate.Obtain(certRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ApplyResult{
|
return &ApplyResult{
|
||||||
|
CSR: strings.TrimSpace(string(certResource.CSR)),
|
||||||
FullChainCertificate: strings.TrimSpace(string(certResource.Certificate)),
|
FullChainCertificate: strings.TrimSpace(string(certResource.Certificate)),
|
||||||
IssuerCertificate: strings.TrimSpace(string(certResource.IssuerCertificate)),
|
IssuerCertificate: strings.TrimSpace(string(certResource.IssuerCertificate)),
|
||||||
PrivateKey: strings.TrimSpace(string(certResource.PrivateKey)),
|
PrivateKey: strings.TrimSpace(string(certResource.PrivateKey)),
|
||||||
ACMEAccountUrl: user.Registration.URI,
|
ACMEAccountUrl: user.Registration.URI,
|
||||||
ACMECertUrl: certResource.CertURL,
|
ACMECertUrl: certResource.CertURL,
|
||||||
ACMECertStableUrl: certResource.CertStableURL,
|
ACMECertStableUrl: certResource.CertStableURL,
|
||||||
CSR: strings.TrimSpace(string(certResource.CSR)),
|
ARIReplaced: certRequest.ReplacesCertID != "",
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ type applicantProviderOptions struct {
|
|||||||
DnsPropagationTimeout int32
|
DnsPropagationTimeout int32
|
||||||
DnsTTL int32
|
DnsTTL int32
|
||||||
DisableFollowCNAME bool
|
DisableFollowCNAME bool
|
||||||
ReplacedARIAcct string
|
ARIReplaceAcct string
|
||||||
ReplacedARICert string
|
ARIReplaceCert string
|
||||||
}
|
}
|
||||||
|
|
||||||
func createApplicantProvider(options *applicantProviderOptions) (challenge.Provider, error) {
|
func createApplicantProvider(options *applicantProviderOptions) (challenge.Provider, error) {
|
||||||
|
@ -28,6 +28,7 @@ type Certificate struct {
|
|||||||
ACMEAccountUrl string `json:"acmeAccountUrl" db:"acmeAccountUrl"`
|
ACMEAccountUrl string `json:"acmeAccountUrl" db:"acmeAccountUrl"`
|
||||||
ACMECertUrl string `json:"acmeCertUrl" db:"acmeCertUrl"`
|
ACMECertUrl string `json:"acmeCertUrl" db:"acmeCertUrl"`
|
||||||
ACMECertStableUrl string `json:"acmeCertStableUrl" db:"acmeCertStableUrl"`
|
ACMECertStableUrl string `json:"acmeCertStableUrl" db:"acmeCertStableUrl"`
|
||||||
|
ACMERenewed bool `json:"acmeRenewed" db:"acmeRenewed"`
|
||||||
WorkflowId string `json:"workflowId" db:"workflowId"`
|
WorkflowId string `json:"workflowId" db:"workflowId"`
|
||||||
WorkflowNodeId string `json:"workflowNodeId" db:"workflowNodeId"`
|
WorkflowNodeId string `json:"workflowNodeId" db:"workflowNodeId"`
|
||||||
WorkflowRunId string `json:"workflowRunId" db:"workflowRunId"`
|
WorkflowRunId string `json:"workflowRunId" db:"workflowRunId"`
|
||||||
|
@ -77,6 +77,25 @@ func (r *CertificateRepository) GetByWorkflowNodeId(ctx context.Context, workflo
|
|||||||
return r.castRecordToModel(records[0])
|
return r.castRecordToModel(records[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *CertificateRepository) GetByWorkflowRunId(ctx context.Context, workflowRunId string) (*domain.Certificate, error) {
|
||||||
|
records, err := app.GetApp().FindRecordsByFilter(
|
||||||
|
domain.CollectionNameCertificate,
|
||||||
|
"workflowRunId={:workflowRunId} && deleted=null",
|
||||||
|
"-created",
|
||||||
|
1, 0,
|
||||||
|
dbx.Params{"workflowRunId": workflowRunId},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(records) == 0 {
|
||||||
|
return nil, domain.ErrRecordNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.castRecordToModel(records[0])
|
||||||
|
}
|
||||||
|
|
||||||
func (r *CertificateRepository) Save(ctx context.Context, certificate *domain.Certificate) (*domain.Certificate, error) {
|
func (r *CertificateRepository) Save(ctx context.Context, certificate *domain.Certificate) (*domain.Certificate, error) {
|
||||||
collection, err := app.GetApp().FindCollectionByNameOrId(domain.CollectionNameCertificate)
|
collection, err := app.GetApp().FindCollectionByNameOrId(domain.CollectionNameCertificate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -109,6 +128,7 @@ func (r *CertificateRepository) Save(ctx context.Context, certificate *domain.Ce
|
|||||||
record.Set("acmeAccountUrl", certificate.ACMEAccountUrl)
|
record.Set("acmeAccountUrl", certificate.ACMEAccountUrl)
|
||||||
record.Set("acmeCertUrl", certificate.ACMECertUrl)
|
record.Set("acmeCertUrl", certificate.ACMECertUrl)
|
||||||
record.Set("acmeCertStableUrl", certificate.ACMECertStableUrl)
|
record.Set("acmeCertStableUrl", certificate.ACMECertStableUrl)
|
||||||
|
record.Set("acmeRenewed", certificate.ACMERenewed)
|
||||||
record.Set("workflowId", certificate.WorkflowId)
|
record.Set("workflowId", certificate.WorkflowId)
|
||||||
record.Set("workflowRunId", certificate.WorkflowRunId)
|
record.Set("workflowRunId", certificate.WorkflowRunId)
|
||||||
record.Set("workflowNodeId", certificate.WorkflowNodeId)
|
record.Set("workflowNodeId", certificate.WorkflowNodeId)
|
||||||
@ -170,6 +190,7 @@ func (r *CertificateRepository) castRecordToModel(record *core.Record) (*domain.
|
|||||||
ACMEAccountUrl: record.GetString("acmeAccountUrl"),
|
ACMEAccountUrl: record.GetString("acmeAccountUrl"),
|
||||||
ACMECertUrl: record.GetString("acmeCertUrl"),
|
ACMECertUrl: record.GetString("acmeCertUrl"),
|
||||||
ACMECertStableUrl: record.GetString("acmeCertStableUrl"),
|
ACMECertStableUrl: record.GetString("acmeCertStableUrl"),
|
||||||
|
ACMERenewed: record.GetBool("acmeRenewed"),
|
||||||
WorkflowId: record.GetString("workflowId"),
|
WorkflowId: record.GetString("workflowId"),
|
||||||
WorkflowRunId: record.GetString("workflowRunId"),
|
WorkflowRunId: record.GetString("workflowRunId"),
|
||||||
WorkflowNodeId: record.GetString("workflowNodeId"),
|
WorkflowNodeId: record.GetString("workflowNodeId"),
|
||||||
|
@ -96,6 +96,15 @@ func (n *applyNode) Process(ctx context.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 保存 ARI 记录
|
||||||
|
if applyResult.ARIReplaced {
|
||||||
|
lastCertificate, _ := n.certRepo.GetByWorkflowRunId(ctx, lastOutput.RunId)
|
||||||
|
if lastCertificate != nil {
|
||||||
|
lastCertificate.ACMERenewed = true
|
||||||
|
n.certRepo.Save(ctx, lastCertificate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
n.logger.Info("apply completed")
|
n.logger.Info("apply completed")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -134,7 +143,7 @@ func (n *applyNode) checkCanSkip(ctx context.Context, lastOutput *domain.Workflo
|
|||||||
return false, "the configuration item 'KeyAlgorithm' changed"
|
return false, "the configuration item 'KeyAlgorithm' changed"
|
||||||
}
|
}
|
||||||
|
|
||||||
lastCertificate, _ := n.certRepo.GetByWorkflowNodeId(ctx, n.node.Id)
|
lastCertificate, _ := n.certRepo.GetByWorkflowRunId(ctx, lastOutput.RunId)
|
||||||
if lastCertificate != nil {
|
if lastCertificate != nil {
|
||||||
renewalInterval := time.Duration(currentNodeConfig.SkipBeforeExpiryDays) * time.Hour * 24
|
renewalInterval := time.Duration(currentNodeConfig.SkipBeforeExpiryDays) * time.Hour * 24
|
||||||
expirationTime := time.Until(lastCertificate.ExpireAt)
|
expirationTime := time.Until(lastCertificate.ExpireAt)
|
||||||
|
@ -34,6 +34,8 @@ func (n *nodeProcessor) SetLogger(logger *slog.Logger) {
|
|||||||
|
|
||||||
type certificateRepository interface {
|
type certificateRepository interface {
|
||||||
GetByWorkflowNodeId(ctx context.Context, workflowNodeId string) (*domain.Certificate, error)
|
GetByWorkflowNodeId(ctx context.Context, workflowNodeId string) (*domain.Certificate, error)
|
||||||
|
GetByWorkflowRunId(ctx context.Context, workflowRunId string) (*domain.Certificate, error)
|
||||||
|
Save(ctx context.Context, certificate *domain.Certificate) (*domain.Certificate, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type workflowOutputRepository interface {
|
type workflowOutputRepository interface {
|
||||||
|
@ -83,7 +83,7 @@ func (n *uploadNode) checkCanSkip(ctx context.Context, lastOutput *domain.Workfl
|
|||||||
return false, "the configuration item 'PrivateKey' changed"
|
return false, "the configuration item 'PrivateKey' changed"
|
||||||
}
|
}
|
||||||
|
|
||||||
lastCertificate, _ := n.certRepo.GetByWorkflowNodeId(ctx, n.node.Id)
|
lastCertificate, _ := n.certRepo.GetByWorkflowRunId(ctx, lastOutput.RunId)
|
||||||
if lastCertificate != nil {
|
if lastCertificate != nil {
|
||||||
return true, "the certificate has already been uploaded"
|
return true, "the certificate has already been uploaded"
|
||||||
}
|
}
|
||||||
|
39
migrations/1748228400_upgrade.go
Normal file
39
migrations/1748228400_upgrade.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
m "github.com/pocketbase/pocketbase/migrations"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
m.Register(func(app core.App) error {
|
||||||
|
// update collection `certificate`
|
||||||
|
{
|
||||||
|
collection, err := app.FindCollectionByNameOrId("4szxr9x43tpj6np")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// add field
|
||||||
|
if err := collection.Fields.AddMarshaledJSONAt(14, []byte(`{
|
||||||
|
"hidden": false,
|
||||||
|
"id": "bool810050391",
|
||||||
|
"name": "acmeRenewed",
|
||||||
|
"presentable": false,
|
||||||
|
"required": false,
|
||||||
|
"system": false,
|
||||||
|
"type": "bool"
|
||||||
|
}`)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := app.Save(collection); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}, func(app core.App) error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user