补齐证书任务入口校验与回归
增加证书导入、恢复、校验任务入口的任务中心回归覆盖,并在任务创建前拒绝无效执行配置,避免异常任务落库。
This commit is contained in:
parent
88d1717656
commit
9741721b1b
@ -5,6 +5,7 @@ import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.pcux.cn/xuans/Scert/backend/internal/certificate"
|
||||
@ -60,9 +61,21 @@ func (w *certificateTaskWorkflow) Validate(ctx context.Context, domainID string)
|
||||
}
|
||||
|
||||
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 {
|
||||
if w == nil || w.tasks == nil || w.audit == nil {
|
||||
return result, errors.New("证书任务记录服务未初始化")
|
||||
}
|
||||
if strings.TrimSpace(id) == "" {
|
||||
return result, errors.New("证书任务域名 ID 不能为空")
|
||||
}
|
||||
if strings.TrimSpace(taskType) == "" || strings.TrimSpace(stage) == "" {
|
||||
return result, errors.New("证书任务类型和阶段不能为空")
|
||||
}
|
||||
if attempts < 1 {
|
||||
return result, errors.New("证书任务至少执行一次")
|
||||
}
|
||||
if execute == nil {
|
||||
return result, errors.New("证书任务执行器未配置")
|
||||
}
|
||||
if active, err := w.tasks.FindActiveTaskByDomain(ctx, id, taskType); err == nil {
|
||||
return result, fmt.Errorf("%w:%s", repository.ErrTaskAlreadyRunning, active.ID)
|
||||
} else if !errors.Is(err, sql.ErrNoRows) {
|
||||
|
||||
@ -218,6 +218,90 @@ func TestCertificateTaskEntryPointsRecordRenewalAndDeployment(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type restoringWorkflowCertificateService struct {
|
||||
workflowCertificateService
|
||||
restored certificate.IssueResult
|
||||
}
|
||||
|
||||
func (s *restoringWorkflowCertificateService) RestoreVersion(context.Context, string, string) (certificate.IssueResult, error) {
|
||||
s.called = true
|
||||
return s.restored, nil
|
||||
}
|
||||
|
||||
func TestCertificateTaskEntryPointsRecordImportRestoreAndValidate(t *testing.T) {
|
||||
t.Run("import", func(t *testing.T) {
|
||||
w, a := newCertificateTaskFixture(t)
|
||||
service := &workflowCertificateService{result: certificate.IssueResult{
|
||||
DomainID: "task-domain",
|
||||
Domains: []string{"task.example.test"},
|
||||
Saved: certificate.SavedResource{CertificatePath: "cert.pem"},
|
||||
}}
|
||||
w.workflow = &CertificateWorkflow{
|
||||
Certificates: service,
|
||||
Domains: &workflowDomainState{},
|
||||
Servers: workflowServerLister{servers: []deployment.Server{{ID: "server"}}},
|
||||
Deployment: &workflowDeployer{report: deployment.Report{Total: 1, Success: 1, Status: "success"}},
|
||||
}
|
||||
_, err := w.Import(t.Context(), certificate.ImportRequest{DomainID: "task-domain", Certificate: "cert.pem", PrivateKey: "key.pem"})
|
||||
if err != nil || !service.called {
|
||||
t.Fatalf("证书导入任务入口执行错误:%v", err)
|
||||
}
|
||||
item := assertCertificateTask(t, a, "success", "success")
|
||||
if item.TaskType != "certificate_import" {
|
||||
t.Fatalf("证书导入任务类型错误:%+v", item)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("restore", func(t *testing.T) {
|
||||
w, a := newCertificateTaskFixture(t)
|
||||
service := &restoringWorkflowCertificateService{workflowCertificateService: workflowCertificateService{
|
||||
result: certificate.IssueResult{DomainID: "task-domain"},
|
||||
}, restored: certificate.IssueResult{DomainID: "task-domain"}}
|
||||
w.workflow = &CertificateWorkflow{Certificates: service}
|
||||
_, err := w.Restore(t.Context(), "task-domain", "version-1")
|
||||
if err != nil || !service.called {
|
||||
t.Fatalf("证书恢复任务入口执行错误:%v", err)
|
||||
}
|
||||
item := assertCertificateTask(t, a, "success", "success")
|
||||
if item.TaskType != "certificate_restore" {
|
||||
t.Fatalf("证书恢复任务类型错误:%+v", item)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("validate", func(t *testing.T) {
|
||||
w, a := newCertificateTaskFixture(t)
|
||||
service := &workflowCertificateService{}
|
||||
w.workflow = &CertificateWorkflow{
|
||||
CurrentCertificate: func(context.Context, string) (certificate.IssueResult, error) {
|
||||
service.called = true
|
||||
return certificate.IssueResult{DomainID: "task-domain"}, nil
|
||||
},
|
||||
}
|
||||
_, _, err := w.Validate(t.Context(), "task-domain")
|
||||
if err == nil || !service.called {
|
||||
t.Fatal("证书校验任务入口未返回预期失败")
|
||||
}
|
||||
item := assertCertificateTask(t, a, "failed", "failed")
|
||||
if item.TaskType != "certificate_validate" {
|
||||
t.Fatalf("证书校验任务类型错误:%+v", item)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestCertificateTaskRejectsInvalidExecutionConfiguration(t *testing.T) {
|
||||
w, a := newCertificateTaskFixture(t)
|
||||
_, err := w.run(t.Context(), "task-domain", "certificate_validate", "certificate_validate", 0, 0, func(context.Context, string) (CertificateWorkflowResult, error) {
|
||||
return CertificateWorkflowResult{}, nil
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), "至少执行一次") {
|
||||
t.Fatalf("无效执行次数未被拒绝:%v", err)
|
||||
}
|
||||
items, listErr := a.Tasks.ListTasks(t.Context(), "task-domain", 10)
|
||||
if listErr != nil || len(items) != 0 {
|
||||
t.Fatalf("无效任务配置不应创建任务:%+v,%v", items, listErr)
|
||||
}
|
||||
}
|
||||
|
||||
type failingCertificateAudit struct {
|
||||
repository.AuditRepository
|
||||
failStatus string
|
||||
|
||||
Loading…
Reference in New Issue
Block a user