补齐证书任务工作流入口

接入证书导入、恢复和校验任务流程,保持现有应用与 HTTP 依赖兼容。
This commit is contained in:
xuans 2026-09-30 02:17:44 +08:00
parent 7e14bbf42f
commit b8997512f9
4 changed files with 124 additions and 58 deletions

View File

@ -170,7 +170,7 @@ func NewWithConfigPath(ctx context.Context, cfg config.Config, configPath string
return certificate.RollbackSavedResource(ctx, saved)
},
ImportCertificate: func(ctx context.Context, request certificate.ImportRequest) (certificate.IssueResult, deployment.Report, error) {
result, err := workflow.Import(ctx, request)
result, err := trackedWorkflow.Import(ctx, request)
return result.Certificate, result.Deployment, err
},
DeployCertificate: func(ctx context.Context, domainID string) (certificate.IssueResult, deployment.Report, error) {
@ -178,7 +178,11 @@ func NewWithConfigPath(ctx context.Context, cfg config.Config, configPath string
return result.Certificate, result.Deployment, err
},
RestoreCertificateVersion: func(ctx context.Context, domainID, version string) (certificate.IssueResult, error) {
return certificates.RestoreVersion(ctx, domainID, version)
result, err := trackedWorkflow.Restore(ctx, domainID, version)
return result.Certificate, err
},
ValidateCertificate: func(ctx context.Context, domainID string) (certificate.IssueResult, certificate.ValidationResult, error) {
return trackedWorkflow.Validate(ctx, domainID)
},
RunRenewal: func(ctx context.Context) (certificate.RenewalReport, error) {
return renewal.RunOnce(ctx)

View File

@ -34,6 +34,29 @@ func (w *certificateTaskWorkflow) DeployCurrent(ctx context.Context, id string)
return w.run(ctx, id, "certificate_deploy", "certificate_deploy", 1, 0, w.workflow.DeployCurrent)
}
func (w *certificateTaskWorkflow) Import(ctx context.Context, request certificate.ImportRequest) (CertificateWorkflowResult, error) {
return w.run(ctx, request.DomainID, "certificate_import", "certificate_import", 1, 0, func(ctx context.Context, _ string) (CertificateWorkflowResult, error) {
return w.workflow.Import(ctx, request)
})
}
func (w *certificateTaskWorkflow) Restore(ctx context.Context, domainID, version string) (CertificateWorkflowResult, error) {
return w.run(ctx, domainID, "certificate_restore", "certificate_restore", 1, 0, func(ctx context.Context, id string) (CertificateWorkflowResult, error) {
result, err := w.workflow.RestoreVersion(ctx, id, version)
return CertificateWorkflowResult{Certificate: result}, err
})
}
func (w *certificateTaskWorkflow) Validate(ctx context.Context, domainID string) (certificate.IssueResult, certificate.ValidationResult, error) {
var validation certificate.ValidationResult
result, err := w.run(ctx, domainID, "certificate_validate", "certificate_validate", 1, 0, func(ctx context.Context, id string) (CertificateWorkflowResult, error) {
certificateResult, validationResult, err := w.workflow.ValidateCurrent(ctx, id)
validation = validationResult
return CertificateWorkflowResult{Certificate: certificateResult}, err
})
return result.Certificate, validation, err
}
func (w *certificateTaskWorkflow) run(ctx context.Context, id, taskType, stage string, attempts int, interval time.Duration, execute func(context.Context, string) (CertificateWorkflowResult, error)) (result CertificateWorkflowResult, resultErr error) {
if w.tasks == nil || w.audit == nil {
return result, errors.New("证书任务记录服务未初始化")

View File

@ -145,6 +145,42 @@ func (w *CertificateWorkflow) Import(ctx context.Context, request certificate.Im
return CertificateWorkflowResult{Certificate: certificateResult, Deployment: report}, err
}
// RestoreVersion restores a certificate version through the certificate service.
func (w *CertificateWorkflow) RestoreVersion(ctx context.Context, domainID, version string) (certificate.IssueResult, error) {
if w == nil || w.Certificates == nil {
return certificate.IssueResult{}, errors.New("证书恢复流程未初始化")
}
restorer, ok := w.Certificates.(interface {
RestoreVersion(context.Context, string, string) (certificate.IssueResult, error)
})
if !ok {
return certificate.IssueResult{}, errors.New("证书恢复服务未配置")
}
return restorer.RestoreVersion(ctx, domainID, version)
}
// ValidateCurrent validates the active certificate through the workflow boundary.
func (w *CertificateWorkflow) ValidateCurrent(ctx context.Context, domainID string) (certificate.IssueResult, certificate.ValidationResult, error) {
if w == nil || w.CurrentCertificate == nil {
return certificate.IssueResult{}, certificate.ValidationResult{}, errors.New("证书校验流程未初始化")
}
result, err := w.CurrentCertificate(ctx, domainID)
if err != nil {
return certificate.IssueResult{}, certificate.ValidationResult{}, err
}
validation, err := (certificate.LocalValidator{VerifyChain: true}).ValidateFiles(
ctx,
result.Saved.CertificatePath,
result.Saved.FullChainPath,
result.Saved.PrivateKeyPath,
result.Domains,
)
if err != nil {
return certificate.IssueResult{}, certificate.ValidationResult{}, fmt.Errorf("当前证书校验失败:%w", err)
}
return result, validation, nil
}
func (w *CertificateWorkflow) notify(ctx context.Context, event notification.Event) {
if w == nil || w.Notifier == nil {
return

View File

@ -64,6 +64,7 @@ type Dependencies struct {
ImportCertificate func(context.Context, certificate.ImportRequest) (certificate.IssueResult, deployment.Report, error)
DeployCertificate func(context.Context, string) (certificate.IssueResult, deployment.Report, error)
RestoreCertificateVersion func(context.Context, string, string) (certificate.IssueResult, error)
ValidateCertificate func(context.Context, string) (certificate.IssueResult, certificate.ValidationResult, error)
RunRenewal func(context.Context) (certificate.RenewalReport, error)
UpdateRenewalPolicy func(certificate.RenewalPolicy)
@ -76,31 +77,32 @@ type Dependencies struct {
}
type Server struct {
configMu sync.RWMutex
config config.Config
configPath string
frontendDir string
logger *logging.Logger
repository repository.DomainRepository
servers repository.ServerRepository
users repository.UserRepository
projectMembers repository.ProjectMemberRepository
projectDirectory repository.ProjectDirectoryRepository
projectLifecycle repository.ProjectLifecycleRepository
projectResources repository.ProjectResourceReader
projectBindings repository.ProjectBindingRepository
projectDomains repository.ProjectDomainRepository
sshKeys *sshkey.Service
deploymentFactory deployment.ClientFactory
setupDNS setupDNSVerifier
secrets setupSecretWriter
firewall firewall.Manager
issueCertificate func(context.Context, string) (certificate.IssueResult, deployment.Report, error)
issueSetupCertificate func(context.Context, certificate.SetupCertificateRequest) (certificate.SavedResource, error)
rollbackSetupCertificate func(context.Context, certificate.SavedResource) error
importCertificate func(context.Context, certificate.ImportRequest) (certificate.IssueResult, deployment.Report, error)
deployCertificate func(context.Context, string) (certificate.IssueResult, deployment.Report, error)
restoreVersion func(context.Context, string, string) (certificate.IssueResult, error)
configMu sync.RWMutex
config config.Config
configPath string
frontendDir string
logger *logging.Logger
repository repository.DomainRepository
servers repository.ServerRepository
users repository.UserRepository
projectMembers repository.ProjectMemberRepository
projectDirectory repository.ProjectDirectoryRepository
projectLifecycle repository.ProjectLifecycleRepository
projectResources repository.ProjectResourceReader
projectBindings repository.ProjectBindingRepository
projectDomains repository.ProjectDomainRepository
sshKeys *sshkey.Service
deploymentFactory deployment.ClientFactory
setupDNS setupDNSVerifier
secrets setupSecretWriter
firewall firewall.Manager
issueCertificate func(context.Context, string) (certificate.IssueResult, deployment.Report, error)
issueSetupCertificate func(context.Context, certificate.SetupCertificateRequest) (certificate.SavedResource, error)
rollbackSetupCertificate func(context.Context, certificate.SavedResource) error
importCertificate func(context.Context, certificate.ImportRequest) (certificate.IssueResult, deployment.Report, error)
deployCertificate func(context.Context, string) (certificate.IssueResult, deployment.Report, error)
restoreVersion func(context.Context, string, string) (certificate.IssueResult, error)
validateCertificateWorkflow func(context.Context, string) (certificate.IssueResult, certificate.ValidationResult, error)
runRenewal func(context.Context) (certificate.RenewalReport, error)
updateRenewalPolicy func(certificate.RenewalPolicy)
@ -148,37 +150,38 @@ func New(deps Dependencies) *Server {
httpListening: make(chan struct{}),
config: deps.Config, configPath: deps.ConfigPath, frontendDir: filepath.Clean(frontendDir), logger: deps.Logger,
repository: deps.Repository, setupDNS: deps.SetupDNS, secrets: deps.Secrets, firewall: deps.Firewall, router: router,
servers: deps.Servers,
users: deps.Users,
projectMembers: deps.ProjectMembers,
projectDirectory: deps.ProjectDirectory,
projectLifecycle: deps.ProjectLifecycle,
projectResources: deps.ProjectResources,
projectBindings: deps.ProjectBindings,
projectDomains: deps.ProjectDomains,
sshKeys: deps.SSHKeys,
deploymentFactory: deps.DeploymentFactory,
issueCertificate: deps.IssueCertificate,
issueSetupCertificate: deps.IssueSetupCertificate,
rollbackSetupCertificate: deps.RollbackSetupCertificate,
importCertificate: deps.ImportCertificate,
deployCertificate: deps.DeployCertificate,
restoreVersion: deps.RestoreCertificateVersion,
runRenewal: deps.RunRenewal,
updateRenewalPolicy: deps.UpdateRenewalPolicy,
currentCertificate: deps.CurrentCertificate,
resetStatePath: deps.ResetStatePath,
audit: deps.Audit,
tasks: deps.Tasks,
readinessCheck: deps.ReadinessCheck,
aliyunChecker: deps.AliyunChecker,
taskCancels: make(map[string]context.CancelFunc),
resetLimiter: newResetRateLimiter(),
authSessions: make(map[string]authSession),
loginAttempts: make(map[string]loginAttempt),
loginSources: make(map[string]loginSource),
loginPending: make(map[string]int),
now: time.Now,
servers: deps.Servers,
users: deps.Users,
projectMembers: deps.ProjectMembers,
projectDirectory: deps.ProjectDirectory,
projectLifecycle: deps.ProjectLifecycle,
projectResources: deps.ProjectResources,
projectBindings: deps.ProjectBindings,
projectDomains: deps.ProjectDomains,
sshKeys: deps.SSHKeys,
deploymentFactory: deps.DeploymentFactory,
issueCertificate: deps.IssueCertificate,
issueSetupCertificate: deps.IssueSetupCertificate,
rollbackSetupCertificate: deps.RollbackSetupCertificate,
importCertificate: deps.ImportCertificate,
deployCertificate: deps.DeployCertificate,
restoreVersion: deps.RestoreCertificateVersion,
validateCertificateWorkflow: deps.ValidateCertificate,
runRenewal: deps.RunRenewal,
updateRenewalPolicy: deps.UpdateRenewalPolicy,
currentCertificate: deps.CurrentCertificate,
resetStatePath: deps.ResetStatePath,
audit: deps.Audit,
tasks: deps.Tasks,
readinessCheck: deps.ReadinessCheck,
aliyunChecker: deps.AliyunChecker,
taskCancels: make(map[string]context.CancelFunc),
resetLimiter: newResetRateLimiter(),
authSessions: make(map[string]authSession),
loginAttempts: make(map[string]loginAttempt),
loginSources: make(map[string]loginSource),
loginPending: make(map[string]int),
now: time.Now,
}
router.Use(server.requestMiddleware())
server.registerRoutes()