mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-15 17:09:51 +00:00
feat: rename san
to subjectAltNames
, workflow
to workflowId
, nodeId
to workflowNodeId
, output
to workflowOutputId
, log
to logs
, succeed
to succeeded
This commit is contained in:
parent
9246878d0e
commit
ae11d5ee3d
@ -2,42 +2,25 @@ package domain
|
||||
|
||||
import "time"
|
||||
|
||||
var ValidityDuration = time.Hour * 24 * 10
|
||||
|
||||
type Certificate struct {
|
||||
Meta
|
||||
SubjectAltNames string `json:"san" db:"san"`
|
||||
Source string `json:"source" db:"source"`
|
||||
SubjectAltNames string `json:"subjectAltNames" db:"subjectAltNames"`
|
||||
Certificate string `json:"certificate" db:"certificate"`
|
||||
PrivateKey string `json:"privateKey" db:"privateKey"`
|
||||
IssuerCertificate string `json:"issuerCertificate" db:"issuerCertificate"`
|
||||
CertUrl string `json:"certUrl" db:"certUrl"`
|
||||
CertStableUrl string `json:"certStableUrl" db:"certStableUrl"`
|
||||
WorkflowId string `json:"workflow" db:"workflow"`
|
||||
WorkflowNodeId string `json:"nodeId" db:"nodeId"`
|
||||
WorkflowOutputId string `json:"output" db:"output"`
|
||||
EffectAt time.Time `json:"effectAt" db:"effectAt"`
|
||||
ExpireAt time.Time `json:"expireAt" db:"expireAt"`
|
||||
AcmeCertUrl string `json:"acmeCertUrl" db:"acmeCertUrl"`
|
||||
AcmeCertStableUrl string `json:"acmeCertStableUrl" db:"acmeCertStableUrl"`
|
||||
WorkflowId string `json:"workflowId" db:"workflowId"`
|
||||
WorkflowNodeId string `json:"workflowNodeId" db:"workflowNodeId"`
|
||||
WorkflowOutputId string `json:"workflowOutputId" db:"workflowOutputId"`
|
||||
}
|
||||
|
||||
type CertificateMeta struct {
|
||||
Version string `json:"version"`
|
||||
SerialNumber string `json:"serialNumber"`
|
||||
Validity CertificateValidity `json:"validity"`
|
||||
SignatureAlgorithm string `json:"signatureAlgorithm"`
|
||||
Issuer CertificateIssuer `json:"issuer"`
|
||||
Subject CertificateSubject `json:"subject"`
|
||||
}
|
||||
type CertificateSourceType string
|
||||
|
||||
type CertificateIssuer struct {
|
||||
Country string `json:"country"`
|
||||
Organization string `json:"organization"`
|
||||
CommonName string `json:"commonName"`
|
||||
}
|
||||
|
||||
type CertificateSubject struct {
|
||||
CN string `json:"CN"`
|
||||
}
|
||||
|
||||
type CertificateValidity struct {
|
||||
NotBefore string `json:"notBefore"`
|
||||
NotAfter string `json:"notAfter"`
|
||||
}
|
||||
const (
|
||||
CERTIFICATE_SOURCE_WORKFLOW = CertificateSourceType("workflow")
|
||||
CERTIFICATE_SOURCE_UPLOAD = CertificateSourceType("upload")
|
||||
)
|
||||
|
@ -4,9 +4,9 @@ const WorkflowOutputCertificate = "certificate"
|
||||
|
||||
type WorkflowOutput struct {
|
||||
Meta
|
||||
Workflow string `json:"workflow"`
|
||||
NodeId string `json:"nodeId"`
|
||||
Node *WorkflowNode `json:"node"`
|
||||
Output []WorkflowNodeIO `json:"output"`
|
||||
Succeed bool `json:"succeed"`
|
||||
WorkflowId string `json:"workflowId" db:"workflowId"`
|
||||
NodeId string `json:"nodeId" db:"nodeId"`
|
||||
Node *WorkflowNode `json:"node" db:"node"`
|
||||
Outputs []WorkflowNodeIO `json:"outputs" db:"outputs"`
|
||||
Succeeded bool `json:"succeeded"db:"succeeded"`
|
||||
}
|
||||
|
@ -1,5 +1,13 @@
|
||||
package domain
|
||||
|
||||
type WorkflowRunLog struct {
|
||||
Meta
|
||||
WorkflowId string `json:"workflowId" db:"workflowId"`
|
||||
Logs []RunLog `json:"logs" db:"logs"`
|
||||
Succeeded bool `json:"succeeded" db:"succeeded"`
|
||||
Error string `json:"error" db:"error"`
|
||||
}
|
||||
|
||||
type RunLogOutput struct {
|
||||
Time string `json:"time"`
|
||||
Title string `json:"title"`
|
||||
@ -8,19 +16,12 @@ type RunLogOutput struct {
|
||||
}
|
||||
|
||||
type RunLog struct {
|
||||
NodeId string `json:"nodeId"`
|
||||
NodeName string `json:"nodeName"`
|
||||
Error string `json:"error"`
|
||||
Outputs []RunLogOutput `json:"outputs"`
|
||||
}
|
||||
|
||||
type WorkflowRunLog struct {
|
||||
Meta
|
||||
Workflow string `json:"workflow"`
|
||||
Log []RunLog `json:"log"`
|
||||
Succeed bool `json:"succeed"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
type RunLogs []RunLog
|
||||
|
||||
func (r RunLogs) Error() string {
|
||||
|
@ -44,9 +44,9 @@ func (w *WorkflowRepository) SaveRunLog(ctx context.Context, log *domain.Workflo
|
||||
}
|
||||
record := models.NewRecord(collection)
|
||||
|
||||
record.Set("workflow", log.Workflow)
|
||||
record.Set("log", log.Log)
|
||||
record.Set("succeed", log.Succeed)
|
||||
record.Set("workflowId", log.WorkflowId)
|
||||
record.Set("logs", log.Logs)
|
||||
record.Set("succeeded", log.Succeeded)
|
||||
record.Set("error", log.Error)
|
||||
|
||||
return app.GetApp().Dao().SaveRecord(record)
|
||||
|
@ -35,8 +35,8 @@ func (w *WorkflowOutputRepository) Get(ctx context.Context, nodeId string) (*dom
|
||||
return nil, errors.New("failed to unmarshal node")
|
||||
}
|
||||
|
||||
output := make([]domain.WorkflowNodeIO, 0)
|
||||
if err := record.UnmarshalJSONField("output", &output); err != nil {
|
||||
outputs := make([]domain.WorkflowNodeIO, 0)
|
||||
if err := record.UnmarshalJSONField("outputs", &outputs); err != nil {
|
||||
return nil, errors.New("failed to unmarshal output")
|
||||
}
|
||||
|
||||
@ -46,18 +46,18 @@ func (w *WorkflowOutputRepository) Get(ctx context.Context, nodeId string) (*dom
|
||||
CreatedAt: record.GetCreated().Time(),
|
||||
UpdatedAt: record.GetUpdated().Time(),
|
||||
},
|
||||
Workflow: record.GetString("workflow"),
|
||||
NodeId: record.GetString("nodeId"),
|
||||
Node: node,
|
||||
Output: output,
|
||||
Succeed: record.GetBool("succeed"),
|
||||
WorkflowId: record.GetString("workflowId"),
|
||||
NodeId: record.GetString("nodeId"),
|
||||
Node: node,
|
||||
Outputs: outputs,
|
||||
Succeeded: record.GetBool("succeeded"),
|
||||
}
|
||||
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
func (w *WorkflowOutputRepository) GetCertificate(ctx context.Context, nodeId string) (*domain.Certificate, error) {
|
||||
records, err := app.GetApp().Dao().FindRecordsByFilter("certificate", "nodeId={:nodeId}", "-created", 1, 0, dbx.Params{"nodeId": nodeId})
|
||||
records, err := app.GetApp().Dao().FindRecordsByFilter("certificate", "workflowNodeId={:workflowNodeId}", "-created", 1, 0, dbx.Params{"workflowNodeId": nodeId})
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, domain.ErrRecordNotFound
|
||||
@ -76,16 +76,18 @@ func (w *WorkflowOutputRepository) GetCertificate(ctx context.Context, nodeId st
|
||||
CreatedAt: record.GetDateTime("created").Time(),
|
||||
UpdatedAt: record.GetDateTime("updated").Time(),
|
||||
},
|
||||
Source: record.GetString("source"),
|
||||
SubjectAltNames: record.GetString("subjectAltNames"),
|
||||
Certificate: record.GetString("certificate"),
|
||||
PrivateKey: record.GetString("privateKey"),
|
||||
IssuerCertificate: record.GetString("issuerCertificate"),
|
||||
SubjectAltNames: record.GetString("san"),
|
||||
WorkflowOutputId: record.GetString("output"),
|
||||
EffectAt: record.GetDateTime("effectAt").Time(),
|
||||
ExpireAt: record.GetDateTime("expireAt").Time(),
|
||||
CertUrl: record.GetString("certUrl"),
|
||||
CertStableUrl: record.GetString("certStableUrl"),
|
||||
WorkflowId: record.GetString("workflow"),
|
||||
WorkflowNodeId: record.GetString("nodeId"),
|
||||
AcmeCertUrl: record.GetString("acmeCertUrl"),
|
||||
AcmeCertStableUrl: record.GetString("acmeCertStableUrl"),
|
||||
WorkflowId: record.GetString("workflowId"),
|
||||
WorkflowNodeId: record.GetString("workflowNodeId"),
|
||||
WorkflowOutputId: record.GetString("workflowOutputId"),
|
||||
}
|
||||
return rs, nil
|
||||
}
|
||||
@ -107,11 +109,11 @@ func (w *WorkflowOutputRepository) Save(ctx context.Context, output *domain.Work
|
||||
return err
|
||||
}
|
||||
}
|
||||
record.Set("workflow", output.Workflow)
|
||||
record.Set("workflowId", output.WorkflowId)
|
||||
record.Set("nodeId", output.NodeId)
|
||||
record.Set("node", output.Node)
|
||||
record.Set("output", output.Output)
|
||||
record.Set("succeed", output.Succeed)
|
||||
record.Set("outputs", output.Outputs)
|
||||
record.Set("succeeded", output.Succeeded)
|
||||
|
||||
if err := app.GetApp().Dao().SaveRecord(record); err != nil {
|
||||
return err
|
||||
@ -128,30 +130,32 @@ func (w *WorkflowOutputRepository) Save(ctx context.Context, output *domain.Work
|
||||
}
|
||||
|
||||
certRecord := models.NewRecord(certCollection)
|
||||
certRecord.Set("source", certificate.Source)
|
||||
certRecord.Set("subjectAltNames", certificate.SubjectAltNames)
|
||||
certRecord.Set("certificate", certificate.Certificate)
|
||||
certRecord.Set("privateKey", certificate.PrivateKey)
|
||||
certRecord.Set("issuerCertificate", certificate.IssuerCertificate)
|
||||
certRecord.Set("san", certificate.SubjectAltNames)
|
||||
certRecord.Set("output", certificate.WorkflowOutputId)
|
||||
certRecord.Set("effectAt", certificate.EffectAt)
|
||||
certRecord.Set("expireAt", certificate.ExpireAt)
|
||||
certRecord.Set("certUrl", certificate.CertUrl)
|
||||
certRecord.Set("certStableUrl", certificate.CertStableUrl)
|
||||
certRecord.Set("workflow", certificate.WorkflowId)
|
||||
certRecord.Set("nodeId", certificate.WorkflowNodeId)
|
||||
certRecord.Set("acmeCertUrl", certificate.AcmeCertUrl)
|
||||
certRecord.Set("acmeCertStableUrl", certificate.AcmeCertStableUrl)
|
||||
certRecord.Set("workflowId", certificate.WorkflowId)
|
||||
certRecord.Set("workflowNodeId", certificate.WorkflowNodeId)
|
||||
certRecord.Set("workflowOutputId", certificate.WorkflowOutputId)
|
||||
|
||||
if err := app.GetApp().Dao().SaveRecord(certRecord); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新 certificate
|
||||
for i, item := range output.Output {
|
||||
for i, item := range output.Outputs {
|
||||
if item.Name == "certificate" {
|
||||
output.Output[i].Value = certRecord.GetId()
|
||||
output.Outputs[i].Value = certRecord.GetId()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
record.Set("output", output.Output)
|
||||
record.Set("outputs", output.Outputs)
|
||||
|
||||
if err := app.GetApp().Dao().SaveRecord(record); err != nil {
|
||||
return err
|
||||
|
@ -64,7 +64,7 @@ func update(ctx context.Context, record *models.Record) error {
|
||||
app.GetApp().Logger().Error("add cron job failed", "err", err)
|
||||
return fmt.Errorf("add cron job failed: %w", err)
|
||||
}
|
||||
app.GetApp().Logger().Error("add cron job failed", "san", record.GetString("san"))
|
||||
app.GetApp().Logger().Error("add cron job failed", "subjectAltNames", record.GetString("subjectAltNames"))
|
||||
|
||||
scheduler.Start()
|
||||
return nil
|
||||
|
@ -17,6 +17,8 @@ type applyNode struct {
|
||||
*Logger
|
||||
}
|
||||
|
||||
var validityDuration = time.Hour * 24 * 10
|
||||
|
||||
func NewApplyNode(node *domain.WorkflowNode) *applyNode {
|
||||
return &applyNode{
|
||||
node: node,
|
||||
@ -46,14 +48,14 @@ func (a *applyNode) Run(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if output != nil && output.Succeed {
|
||||
if output != nil && output.Succeeded {
|
||||
cert, err := a.outputRepo.GetCertificate(ctx, a.node.Id)
|
||||
if err != nil {
|
||||
a.AddOutput(ctx, a.node.Name, "获取证书失败", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
if time.Until(cert.ExpireAt) > domain.ValidityDuration {
|
||||
if time.Until(cert.ExpireAt) > validityDuration {
|
||||
a.AddOutput(ctx, a.node.Name, "已申请过证书,且证书在有效期内")
|
||||
return nil
|
||||
}
|
||||
@ -81,28 +83,30 @@ func (a *applyNode) Run(ctx context.Context) error {
|
||||
outputId = output.Id
|
||||
}
|
||||
output = &domain.WorkflowOutput{
|
||||
Workflow: GetWorkflowId(ctx),
|
||||
NodeId: a.node.Id,
|
||||
Node: a.node,
|
||||
Succeed: true,
|
||||
Output: a.node.Output,
|
||||
Meta: domain.Meta{Id: outputId},
|
||||
Meta: domain.Meta{Id: outputId},
|
||||
WorkflowId: GetWorkflowId(ctx),
|
||||
NodeId: a.node.Id,
|
||||
Node: a.node,
|
||||
Succeeded: true,
|
||||
Outputs: a.node.Output,
|
||||
}
|
||||
|
||||
cert, err := x509.ParseCertificateFromPEM(certificate.Certificate)
|
||||
certX509, err := x509.ParseCertificateFromPEM(certificate.Certificate)
|
||||
if err != nil {
|
||||
a.AddOutput(ctx, a.node.Name, "解析证书失败", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
certificateRecord := &domain.Certificate{
|
||||
SubjectAltNames: strings.Join(cert.DNSNames, ";"),
|
||||
Source: string(domain.CERTIFICATE_SOURCE_WORKFLOW),
|
||||
SubjectAltNames: strings.Join(certX509.DNSNames, ";"),
|
||||
Certificate: certificate.Certificate,
|
||||
PrivateKey: certificate.PrivateKey,
|
||||
IssuerCertificate: certificate.IssuerCertificate,
|
||||
CertUrl: certificate.CertUrl,
|
||||
CertStableUrl: certificate.CertStableUrl,
|
||||
ExpireAt: cert.NotAfter,
|
||||
AcmeCertUrl: certificate.CertUrl,
|
||||
AcmeCertStableUrl: certificate.CertStableUrl,
|
||||
EffectAt: certX509.NotBefore,
|
||||
ExpireAt: certX509.NotAfter,
|
||||
WorkflowId: GetWorkflowId(ctx),
|
||||
WorkflowNodeId: a.node.Id,
|
||||
}
|
||||
|
@ -71,8 +71,8 @@ func (d *deployNode) Run(ctx context.Context) error {
|
||||
AccessConfig: access.Config,
|
||||
AccessRecord: access,
|
||||
Certificate: applicant.Certificate{
|
||||
CertUrl: cert.CertUrl,
|
||||
CertStableUrl: cert.CertStableUrl,
|
||||
CertUrl: cert.AcmeCertUrl,
|
||||
CertStableUrl: cert.AcmeCertStableUrl,
|
||||
PrivateKey: cert.PrivateKey,
|
||||
Certificate: cert.Certificate,
|
||||
IssuerCertificate: cert.IssuerCertificate,
|
||||
@ -105,11 +105,11 @@ func (d *deployNode) Run(ctx context.Context) error {
|
||||
outputId = output.Id
|
||||
}
|
||||
output = &domain.WorkflowOutput{
|
||||
Workflow: GetWorkflowId(ctx),
|
||||
NodeId: d.node.Id,
|
||||
Node: d.node,
|
||||
Succeed: true,
|
||||
Meta: domain.Meta{Id: outputId},
|
||||
Meta: domain.Meta{Id: outputId},
|
||||
WorkflowId: GetWorkflowId(ctx),
|
||||
NodeId: d.node.Id,
|
||||
Node: d.node,
|
||||
Succeeded: true,
|
||||
}
|
||||
|
||||
if err := d.outputRepo.Save(ctx, output, nil, nil); err != nil {
|
||||
@ -123,5 +123,5 @@ func (d *deployNode) Run(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (d *deployNode) deployed(output *domain.WorkflowOutput) bool {
|
||||
return output != nil && output.Succeed
|
||||
return output != nil && output.Succeeded
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ type Logger struct {
|
||||
func NewLogger(node *domain.WorkflowNode) *Logger {
|
||||
return &Logger{
|
||||
log: &domain.RunLog{
|
||||
NodeId: node.Id,
|
||||
NodeName: node.Name,
|
||||
Outputs: make([]domain.RunLogOutput, 0),
|
||||
},
|
||||
|
@ -69,10 +69,10 @@ func (s *WorkflowService) Run(ctx context.Context, req *domain.WorkflowRunReq) e
|
||||
processor := nodeprocessor.NewWorkflowProcessor(workflow)
|
||||
if err := processor.Run(ctx); err != nil {
|
||||
log := &domain.WorkflowRunLog{
|
||||
Workflow: workflow.Id,
|
||||
Log: processor.Log(ctx),
|
||||
Succeed: false,
|
||||
Error: err.Error(),
|
||||
WorkflowId: workflow.Id,
|
||||
Logs: processor.Log(ctx),
|
||||
Succeeded: false,
|
||||
Error: err.Error(),
|
||||
}
|
||||
if err := s.repo.SaveRunLog(ctx, log); err != nil {
|
||||
app.GetApp().Logger().Error("failed to save run log", "err", err)
|
||||
@ -89,10 +89,10 @@ func (s *WorkflowService) Run(ctx context.Context, req *domain.WorkflowRunReq) e
|
||||
succeed = false
|
||||
}
|
||||
log := &domain.WorkflowRunLog{
|
||||
Workflow: workflow.Id,
|
||||
Log: processor.Log(ctx),
|
||||
Error: runErr,
|
||||
Succeed: succeed,
|
||||
WorkflowId: workflow.Id,
|
||||
Logs: processor.Log(ctx),
|
||||
Error: runErr,
|
||||
Succeeded: succeed,
|
||||
}
|
||||
if err := s.repo.SaveRunLog(ctx, log); err != nil {
|
||||
app.GetApp().Logger().Error("failed to save run log", "err", err)
|
||||
|
298
migrations/1735976342_updated_certificate.go
Normal file
298
migrations/1735976342_updated_certificate.go
Normal file
@ -0,0 +1,298 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/daos"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
"github.com/pocketbase/pocketbase/models/schema"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(db dbx.Builder) error {
|
||||
dao := daos.New(db);
|
||||
|
||||
collection, err := dao.FindCollectionByNameOrId("4szxr9x43tpj6np")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add
|
||||
new_effectAt := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "v40aqzpd",
|
||||
"name": "effectAt",
|
||||
"type": "date",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"min": "",
|
||||
"max": ""
|
||||
}
|
||||
}`), new_effectAt); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(new_effectAt)
|
||||
|
||||
// update
|
||||
edit_subjectAltNames := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "fugxf58p",
|
||||
"name": "subjectAltNames",
|
||||
"type": "text",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"min": null,
|
||||
"max": null,
|
||||
"pattern": ""
|
||||
}
|
||||
}`), edit_subjectAltNames); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_subjectAltNames)
|
||||
|
||||
// update
|
||||
edit_acmeCertUrl := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "ayyjy5ve",
|
||||
"name": "acmeCertUrl",
|
||||
"type": "url",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"exceptDomains": null,
|
||||
"onlyDomains": null
|
||||
}
|
||||
}`), edit_acmeCertUrl); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_acmeCertUrl)
|
||||
|
||||
// update
|
||||
edit_acmeCertStableUrl := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "3x5heo8e",
|
||||
"name": "acmeCertStableUrl",
|
||||
"type": "url",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"exceptDomains": null,
|
||||
"onlyDomains": null
|
||||
}
|
||||
}`), edit_acmeCertStableUrl); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_acmeCertStableUrl)
|
||||
|
||||
// update
|
||||
edit_workflowId := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "uvqfamb1",
|
||||
"name": "workflowId",
|
||||
"type": "relation",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"collectionId": "tovyif5ax6j62ur",
|
||||
"cascadeDelete": false,
|
||||
"minSelect": null,
|
||||
"maxSelect": 1,
|
||||
"displayFields": null
|
||||
}
|
||||
}`), edit_workflowId); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_workflowId)
|
||||
|
||||
// update
|
||||
edit_workflowNodeId := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "uqldzldw",
|
||||
"name": "workflowNodeId",
|
||||
"type": "text",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"min": null,
|
||||
"max": null,
|
||||
"pattern": ""
|
||||
}
|
||||
}`), edit_workflowNodeId); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_workflowNodeId)
|
||||
|
||||
// update
|
||||
edit_workflowOutputId := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "2ohlr0yd",
|
||||
"name": "workflowOutputId",
|
||||
"type": "relation",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"collectionId": "bqnxb95f2cooowp",
|
||||
"cascadeDelete": false,
|
||||
"minSelect": null,
|
||||
"maxSelect": 1,
|
||||
"displayFields": null
|
||||
}
|
||||
}`), edit_workflowOutputId); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_workflowOutputId)
|
||||
|
||||
return dao.SaveCollection(collection)
|
||||
}, func(db dbx.Builder) error {
|
||||
dao := daos.New(db);
|
||||
|
||||
collection, err := dao.FindCollectionByNameOrId("4szxr9x43tpj6np")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove
|
||||
collection.Schema.RemoveField("v40aqzpd")
|
||||
|
||||
// update
|
||||
edit_subjectAltNames := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "fugxf58p",
|
||||
"name": "san",
|
||||
"type": "text",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"min": null,
|
||||
"max": null,
|
||||
"pattern": ""
|
||||
}
|
||||
}`), edit_subjectAltNames); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_subjectAltNames)
|
||||
|
||||
// update
|
||||
edit_acmeCertUrl := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "ayyjy5ve",
|
||||
"name": "certUrl",
|
||||
"type": "url",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"exceptDomains": null,
|
||||
"onlyDomains": null
|
||||
}
|
||||
}`), edit_acmeCertUrl); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_acmeCertUrl)
|
||||
|
||||
// update
|
||||
edit_acmeCertStableUrl := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "3x5heo8e",
|
||||
"name": "certStableUrl",
|
||||
"type": "url",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"exceptDomains": null,
|
||||
"onlyDomains": null
|
||||
}
|
||||
}`), edit_acmeCertStableUrl); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_acmeCertStableUrl)
|
||||
|
||||
// update
|
||||
edit_workflowId := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "uvqfamb1",
|
||||
"name": "workflow",
|
||||
"type": "relation",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"collectionId": "tovyif5ax6j62ur",
|
||||
"cascadeDelete": false,
|
||||
"minSelect": null,
|
||||
"maxSelect": 1,
|
||||
"displayFields": null
|
||||
}
|
||||
}`), edit_workflowId); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_workflowId)
|
||||
|
||||
// update
|
||||
edit_workflowNodeId := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "uqldzldw",
|
||||
"name": "nodeId",
|
||||
"type": "text",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"min": null,
|
||||
"max": null,
|
||||
"pattern": ""
|
||||
}
|
||||
}`), edit_workflowNodeId); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_workflowNodeId)
|
||||
|
||||
// update
|
||||
edit_workflowOutputId := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "2ohlr0yd",
|
||||
"name": "output",
|
||||
"type": "relation",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"collectionId": "bqnxb95f2cooowp",
|
||||
"cascadeDelete": false,
|
||||
"minSelect": null,
|
||||
"maxSelect": 1,
|
||||
"displayFields": null
|
||||
}
|
||||
}`), edit_workflowOutputId); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_workflowOutputId)
|
||||
|
||||
return dao.SaveCollection(collection)
|
||||
})
|
||||
}
|
144
migrations/1735977005_updated_workflow_output.go
Normal file
144
migrations/1735977005_updated_workflow_output.go
Normal file
@ -0,0 +1,144 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/daos"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
"github.com/pocketbase/pocketbase/models/schema"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(db dbx.Builder) error {
|
||||
dao := daos.New(db);
|
||||
|
||||
collection, err := dao.FindCollectionByNameOrId("bqnxb95f2cooowp")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update
|
||||
edit_workflowId := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "jka88auc",
|
||||
"name": "workflowId",
|
||||
"type": "relation",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"collectionId": "tovyif5ax6j62ur",
|
||||
"cascadeDelete": false,
|
||||
"minSelect": null,
|
||||
"maxSelect": 1,
|
||||
"displayFields": null
|
||||
}
|
||||
}`), edit_workflowId); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_workflowId)
|
||||
|
||||
// update
|
||||
edit_outputs := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "he4cceqb",
|
||||
"name": "outputs",
|
||||
"type": "json",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"maxSize": 2000000
|
||||
}
|
||||
}`), edit_outputs); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_outputs)
|
||||
|
||||
// update
|
||||
edit_succeeded := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "2yfxbxuf",
|
||||
"name": "succeeded",
|
||||
"type": "bool",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {}
|
||||
}`), edit_succeeded); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_succeeded)
|
||||
|
||||
return dao.SaveCollection(collection)
|
||||
}, func(db dbx.Builder) error {
|
||||
dao := daos.New(db);
|
||||
|
||||
collection, err := dao.FindCollectionByNameOrId("bqnxb95f2cooowp")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update
|
||||
edit_workflowId := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "jka88auc",
|
||||
"name": "workflow",
|
||||
"type": "relation",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"collectionId": "tovyif5ax6j62ur",
|
||||
"cascadeDelete": false,
|
||||
"minSelect": null,
|
||||
"maxSelect": 1,
|
||||
"displayFields": null
|
||||
}
|
||||
}`), edit_workflowId); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_workflowId)
|
||||
|
||||
// update
|
||||
edit_outputs := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "he4cceqb",
|
||||
"name": "output",
|
||||
"type": "json",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"maxSize": 2000000
|
||||
}
|
||||
}`), edit_outputs); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_outputs)
|
||||
|
||||
// update
|
||||
edit_succeeded := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "2yfxbxuf",
|
||||
"name": "succeed",
|
||||
"type": "bool",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {}
|
||||
}`), edit_succeeded); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_succeeded)
|
||||
|
||||
return dao.SaveCollection(collection)
|
||||
})
|
||||
}
|
144
migrations/1735977021_updated_workflow_run_log.go
Normal file
144
migrations/1735977021_updated_workflow_run_log.go
Normal file
@ -0,0 +1,144 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/daos"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
"github.com/pocketbase/pocketbase/models/schema"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(db dbx.Builder) error {
|
||||
dao := daos.New(db);
|
||||
|
||||
collection, err := dao.FindCollectionByNameOrId("qjp8lygssgwyqyz")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update
|
||||
edit_workflowId := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "m8xfsyyy",
|
||||
"name": "workflowId",
|
||||
"type": "relation",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"collectionId": "tovyif5ax6j62ur",
|
||||
"cascadeDelete": false,
|
||||
"minSelect": null,
|
||||
"maxSelect": 1,
|
||||
"displayFields": null
|
||||
}
|
||||
}`), edit_workflowId); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_workflowId)
|
||||
|
||||
// update
|
||||
edit_logs := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "2m9byaa9",
|
||||
"name": "logs",
|
||||
"type": "json",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"maxSize": 2000000
|
||||
}
|
||||
}`), edit_logs); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_logs)
|
||||
|
||||
// update
|
||||
edit_succeeded := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "cht6kqw9",
|
||||
"name": "succeeded",
|
||||
"type": "bool",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {}
|
||||
}`), edit_succeeded); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_succeeded)
|
||||
|
||||
return dao.SaveCollection(collection)
|
||||
}, func(db dbx.Builder) error {
|
||||
dao := daos.New(db);
|
||||
|
||||
collection, err := dao.FindCollectionByNameOrId("qjp8lygssgwyqyz")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update
|
||||
edit_workflowId := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "m8xfsyyy",
|
||||
"name": "workflow",
|
||||
"type": "relation",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"collectionId": "tovyif5ax6j62ur",
|
||||
"cascadeDelete": false,
|
||||
"minSelect": null,
|
||||
"maxSelect": 1,
|
||||
"displayFields": null
|
||||
}
|
||||
}`), edit_workflowId); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_workflowId)
|
||||
|
||||
// update
|
||||
edit_logs := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "2m9byaa9",
|
||||
"name": "log",
|
||||
"type": "json",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"maxSize": 2000000
|
||||
}
|
||||
}`), edit_logs); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_logs)
|
||||
|
||||
// update
|
||||
edit_succeeded := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "cht6kqw9",
|
||||
"name": "succeed",
|
||||
"type": "bool",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {}
|
||||
}`), edit_succeeded); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(edit_succeeded)
|
||||
|
||||
return dao.SaveCollection(collection)
|
||||
})
|
||||
}
|
57
migrations/1735977530_updated_certificate.go
Normal file
57
migrations/1735977530_updated_certificate.go
Normal file
@ -0,0 +1,57 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/daos"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
"github.com/pocketbase/pocketbase/models/schema"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(db dbx.Builder) error {
|
||||
dao := daos.New(db);
|
||||
|
||||
collection, err := dao.FindCollectionByNameOrId("4szxr9x43tpj6np")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add
|
||||
new_source := &schema.SchemaField{}
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"system": false,
|
||||
"id": "by9hetqi",
|
||||
"name": "source",
|
||||
"type": "select",
|
||||
"required": false,
|
||||
"presentable": false,
|
||||
"unique": false,
|
||||
"options": {
|
||||
"maxSelect": 1,
|
||||
"values": [
|
||||
"workflow",
|
||||
"upload"
|
||||
]
|
||||
}
|
||||
}`), new_source); err != nil {
|
||||
return err
|
||||
}
|
||||
collection.Schema.AddField(new_source)
|
||||
|
||||
return dao.SaveCollection(collection)
|
||||
}, func(db dbx.Builder) error {
|
||||
dao := daos.New(db);
|
||||
|
||||
collection, err := dao.FindCollectionByNameOrId("4szxr9x43tpj6np")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove
|
||||
collection.Schema.RemoveField("by9hetqi")
|
||||
|
||||
return dao.SaveCollection(collection)
|
||||
})
|
||||
}
|
@ -19,14 +19,14 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => {
|
||||
const [messageApi, MessageContextHolder] = message.useMessage();
|
||||
|
||||
const handleDownloadPEMClick = async () => {
|
||||
const zipName = `${data.id}-${data.san}.zip`;
|
||||
const zipName = `${data.id}-${data.subjectAltNames}.zip`;
|
||||
const files = [
|
||||
{
|
||||
name: `${data.san}.pem`,
|
||||
name: `${data.subjectAltNames}.pem`,
|
||||
content: data.certificate ?? "",
|
||||
},
|
||||
{
|
||||
name: `${data.san}.key`,
|
||||
name: `${data.subjectAltNames}.key`,
|
||||
content: data.privateKey ?? "",
|
||||
},
|
||||
];
|
||||
@ -39,17 +39,17 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => {
|
||||
{MessageContextHolder}
|
||||
|
||||
<Form layout="vertical">
|
||||
<Form.Item label={t("certificate.props.san")}>
|
||||
<Input value={data.san} placeholder="" />
|
||||
<Form.Item label={t("certificate.props.subject_alt_names")}>
|
||||
<Input value={data.subjectAltNames} placeholder="" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label={t("certificate.props.expiry")}>
|
||||
<Input value={dayjs(data.expireAt).format("YYYY-MM-DD HH:mm:ss")} placeholder="" />
|
||||
<Form.Item label={t("certificate.props.validity")}>
|
||||
<Input value={`${dayjs(data.effectAt).format("YYYY-MM-DD HH:mm:ss")} ~ ${dayjs(data.expireAt).format("YYYY-MM-DD HH:mm:ss")}`} placeholder="" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<div className="mb-2 flex w-full items-center justify-between">
|
||||
<label>{t("certificate.props.certificate_chain")}</label>
|
||||
<label>{t("certificate.props.certificate")}</label>
|
||||
<Tooltip title={t("common.button.copy")}>
|
||||
<CopyToClipboard
|
||||
text={data.certificate}
|
||||
|
@ -68,7 +68,7 @@ const WorkflowElement = ({ node, disabled }: NodeProps) => {
|
||||
return (
|
||||
<Space>
|
||||
<Avatar src={provider?.icon} size="small" />
|
||||
<Typography.Text className="truncate">{t(provider?.name ?? " ")}</Typography.Text>
|
||||
<Typography.Text className="truncate">{t(provider?.name ?? "")}</Typography.Text>
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
@ -80,7 +80,7 @@ const WorkflowElement = ({ node, disabled }: NodeProps) => {
|
||||
<div className="flex items-center justify-between space-x-2">
|
||||
<Typography.Text className="truncate">{t(channel?.name ?? " ")}</Typography.Text>
|
||||
<Typography.Text className="truncate" type="secondary">
|
||||
{(node.config?.subject as string) ?? ""}
|
||||
{config.subject ?? ""}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
);
|
||||
|
@ -32,7 +32,7 @@ const WorkflowRunDetailDrawer = ({ data, loading, trigger, ...props }: WorkflowR
|
||||
|
||||
<Drawer destroyOnClose open={open} loading={loading} placement="right" title={`runlog-${data?.id}`} width={640} onClose={() => setOpen(false)}>
|
||||
<Show when={!!data}>
|
||||
<Show when={data!.succeed}>
|
||||
<Show when={data!.succeeded}>
|
||||
<Alert showIcon type="success" message={<Typography.Text type="success">{t("workflow_run.props.status.succeeded")}</Typography.Text>} />
|
||||
</Show>
|
||||
|
||||
@ -42,7 +42,7 @@ const WorkflowRunDetailDrawer = ({ data, loading, trigger, ...props }: WorkflowR
|
||||
|
||||
<div className="mt-4 rounded-md bg-black p-4 text-stone-200">
|
||||
<div className="flex flex-col space-y-3">
|
||||
{data!.log.map((item, i) => {
|
||||
{data!.logs.map((item, i) => {
|
||||
return (
|
||||
<div key={i} className="flex flex-col space-y-2">
|
||||
<div>{item.nodeName}</div>
|
||||
|
@ -46,7 +46,7 @@ const WorkflowRuns = ({ className, style, workflowId }: WorkflowRunsProps) => {
|
||||
title: t("workflow_run.props.status"),
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
if (record.succeed) {
|
||||
if (record.succeeded) {
|
||||
return (
|
||||
<Space>
|
||||
<CheckCircleOutlinedIcon style={{ color: themeToken.colorSuccess }} />
|
||||
|
@ -1,17 +1,21 @@
|
||||
import { type WorkflowModel } from "./workflow";
|
||||
|
||||
export interface CertificateModel extends BaseModel {
|
||||
san: string;
|
||||
source: string;
|
||||
subjectAltNames: string;
|
||||
certificate: string;
|
||||
privateKey: string;
|
||||
issuerCertificate: string;
|
||||
certUrl: string;
|
||||
certStableUrl: string;
|
||||
output: string;
|
||||
effectAt: ISO8601String;
|
||||
expireAt: ISO8601String;
|
||||
workflow: string;
|
||||
nodeId: string;
|
||||
workflowId: string;
|
||||
expand: {
|
||||
workflow?: WorkflowModel;
|
||||
workflowId?: WorkflowModel; // TODO: ugly, maybe to use an alias?
|
||||
};
|
||||
}
|
||||
|
||||
export const CERTIFICATE_SOURCES = Object.freeze({
|
||||
WORKFLOW: "workflow",
|
||||
UPLOAD: "upload",
|
||||
} as const);
|
||||
|
||||
export type CertificateSourceType = (typeof CERTIFICATE_SOURCES)[keyof typeof CERTIFICATE_SOURCES];
|
||||
|
@ -400,9 +400,10 @@ export const isAllNodesValidated = (node: WorkflowNode): boolean => {
|
||||
*/
|
||||
export const getExecuteMethod = (node: WorkflowNode): { trigger: string; triggerCron: string } => {
|
||||
if (node.type === WorkflowNodeType.Start) {
|
||||
const config = node.config as WorkflowNodeConfigAsStart;
|
||||
return {
|
||||
trigger: (node.config?.trigger as string) ?? "",
|
||||
triggerCron: (node.config?.triggerCron as string) ?? "",
|
||||
trigger: config.trigger ?? "",
|
||||
triggerCron: config.triggerCron ?? "",
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
|
@ -1,14 +1,15 @@
|
||||
export interface WorkflowRunModel extends BaseModel {
|
||||
workflow: string;
|
||||
log: WorkflowRunLog[];
|
||||
workflowId: string;
|
||||
logs: WorkflowRunLog[];
|
||||
error: string;
|
||||
succeed: boolean;
|
||||
succeeded: boolean;
|
||||
}
|
||||
|
||||
export type WorkflowRunLog = {
|
||||
nodeId: string;
|
||||
nodeName: string;
|
||||
error: string;
|
||||
outputs: WorkflowRunLogOutput[];
|
||||
error: string;
|
||||
};
|
||||
|
||||
export type WorkflowRunLogOutput = {
|
||||
|
@ -7,17 +7,17 @@
|
||||
"certificate.action.delete": "Delete certificate",
|
||||
"certificate.action.download": "Download certificate",
|
||||
|
||||
"certificate.props.san": "Name",
|
||||
"certificate.props.expiry": "Expiry",
|
||||
"certificate.props.expiry.left_days": "{{left}} / {{total}} days left",
|
||||
"certificate.props.expiry.expired": "Expired",
|
||||
"certificate.props.expiry.expiration": "Expire on {{date}}",
|
||||
"certificate.props.expiry.filter.expire_soon": "Expire soon",
|
||||
"certificate.props.expiry.filter.expired": "Expired",
|
||||
"certificate.props.workflow": "Workflow",
|
||||
"certificate.props.subject_alt_names": "Name",
|
||||
"certificate.props.validity": "Expiry",
|
||||
"certificate.props.validity.left_days": "{{left}} / {{total}} days left",
|
||||
"certificate.props.validity.expired": "Expired",
|
||||
"certificate.props.validity.expiration": "Expire on {{date}}",
|
||||
"certificate.props.validity.filter.expire_soon": "Expire soon",
|
||||
"certificate.props.validity.filter.expired": "Expired",
|
||||
"certificate.props.source": "Source",
|
||||
"certificate.props.source.workflow": "Workflow",
|
||||
"certificate.props.certificate_chain": "Certificate chain",
|
||||
"certificate.props.source.upload": "Upload",
|
||||
"certificate.props.certificate": "Certificate chain",
|
||||
"certificate.props.private_key": "Private key",
|
||||
"certificate.props.created_at": "Created at",
|
||||
"certificate.props.updated_at": "Updated at"
|
||||
|
@ -7,17 +7,17 @@
|
||||
"certificate.action.delete": "删除证书",
|
||||
"certificate.action.download": "下载证书",
|
||||
|
||||
"certificate.props.san": "名称",
|
||||
"certificate.props.expiry": "有效期限",
|
||||
"certificate.props.expiry.left_days": "{{left}} / {{total}} 天",
|
||||
"certificate.props.expiry.expired": "已到期",
|
||||
"certificate.props.expiry.expiration": "{{date}} 到期",
|
||||
"certificate.props.expiry.filter.expire_soon": "即将到期",
|
||||
"certificate.props.expiry.filter.expired": "已到期",
|
||||
"certificate.props.workflow": "所属工作流",
|
||||
"certificate.props.subject_alt_names": "名称",
|
||||
"certificate.props.validity": "有效期限",
|
||||
"certificate.props.validity.left_days": "{{left}} / {{total}} 天",
|
||||
"certificate.props.validity.expired": "已到期",
|
||||
"certificate.props.validity.expiration": "{{date}} 到期",
|
||||
"certificate.props.validity.filter.expire_soon": "即将到期",
|
||||
"certificate.props.validity.filter.expired": "已到期",
|
||||
"certificate.props.source": "来源",
|
||||
"certificate.props.source.workflow": "工作流",
|
||||
"certificate.props.certificate_chain": "证书内容",
|
||||
"certificate.props.source.upload": "用户上传",
|
||||
"certificate.props.certificate": "证书内容",
|
||||
"certificate.props.private_key": "私钥内容",
|
||||
"certificate.props.created_at": "创建时间",
|
||||
"certificate.props.updated_at": "更新时间"
|
||||
|
@ -9,7 +9,7 @@ import dayjs from "dayjs";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
|
||||
import CertificateDetailDrawer from "@/components/certificate/CertificateDetailDrawer";
|
||||
import { type CertificateModel } from "@/domain/certificate";
|
||||
import { CERTIFICATE_SOURCES, type CertificateModel } from "@/domain/certificate";
|
||||
import { type ListCertificateRequest, list as listCertificate } from "@/repository/certificate";
|
||||
import { getErrMsg } from "@/utils/error";
|
||||
|
||||
@ -33,18 +33,18 @@ const CertificateList = () => {
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
title: t("certificate.props.san"),
|
||||
render: (_, record) => <Typography.Text>{record.san}</Typography.Text>,
|
||||
title: t("certificate.props.subject_alt_names"),
|
||||
render: (_, record) => <Typography.Text>{record.subjectAltNames}</Typography.Text>,
|
||||
},
|
||||
{
|
||||
key: "expiry",
|
||||
title: t("certificate.props.expiry"),
|
||||
title: t("certificate.props.validity"),
|
||||
ellipsis: true,
|
||||
defaultFilteredValue: searchParams.has("state") ? [searchParams.get("state") as string] : undefined,
|
||||
filterDropdown: ({ setSelectedKeys, confirm, clearFilters }) => {
|
||||
const items: Required<MenuProps>["items"] = [
|
||||
["expireSoon", "certificate.props.expiry.filter.expire_soon"],
|
||||
["expired", "certificate.props.expiry.filter.expired"],
|
||||
["expireSoon", "certificate.props.validity.filter.expire_soon"],
|
||||
["expired", "certificate.props.validity.filter.expired"],
|
||||
].map(([key, label]) => {
|
||||
return {
|
||||
key,
|
||||
@ -94,13 +94,13 @@ const CertificateList = () => {
|
||||
return (
|
||||
<Space className="max-w-full" direction="vertical" size={4}>
|
||||
{left > 0 ? (
|
||||
<Typography.Text type="success">{t("certificate.props.expiry.left_days", { left, total })}</Typography.Text>
|
||||
<Typography.Text type="success">{t("certificate.props.validity.left_days", { left, total })}</Typography.Text>
|
||||
) : (
|
||||
<Typography.Text type="danger">{t("certificate.props.expiry.expired")}</Typography.Text>
|
||||
<Typography.Text type="danger">{t("certificate.props.validity.expired")}</Typography.Text>
|
||||
)}
|
||||
|
||||
<Typography.Text type="secondary">
|
||||
{t("certificate.props.expiry.expiration", { date: dayjs(record.expireAt).format("YYYY-MM-DD") })}
|
||||
{t("certificate.props.validity.expiration", { date: dayjs(record.expireAt).format("YYYY-MM-DD") })}
|
||||
</Typography.Text>
|
||||
</Space>
|
||||
);
|
||||
@ -111,23 +111,29 @@ const CertificateList = () => {
|
||||
title: t("certificate.props.source"),
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
const workflowId = record.workflow;
|
||||
return workflowId ? (
|
||||
<Space className="max-w-full" direction="vertical" size={4}>
|
||||
<Typography.Text>{t("certificate.props.source.workflow")}</Typography.Text>
|
||||
<Typography.Link
|
||||
type="secondary"
|
||||
ellipsis
|
||||
onClick={() => {
|
||||
navigate(`/workflows/${workflowId}`);
|
||||
}}
|
||||
>
|
||||
{record.expand?.workflow?.name ?? ""}
|
||||
</Typography.Link>
|
||||
</Space>
|
||||
) : (
|
||||
<>TODO: 支持手动上传</>
|
||||
);
|
||||
if (record.source === CERTIFICATE_SOURCES.WORKFLOW) {
|
||||
const workflowId = record.workflowId;
|
||||
return (
|
||||
<Space className="max-w-full" direction="vertical" size={4}>
|
||||
<Typography.Text>{t("certificate.props.source.workflow")}</Typography.Text>
|
||||
<Typography.Link
|
||||
type="secondary"
|
||||
ellipsis
|
||||
onClick={() => {
|
||||
if (workflowId) {
|
||||
navigate(`/workflows/${workflowId}`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{record.expand?.workflowId?.name ?? `#${workflowId}`}
|
||||
</Typography.Link>
|
||||
</Space>
|
||||
);
|
||||
} else if (record.source === CERTIFICATE_SOURCES.UPLOAD) {
|
||||
return <Typography.Text>{t("certificate.props.source.upload")}</Typography.Text>;
|
||||
}
|
||||
|
||||
return <></>;
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ export const list = async (request: ListCertificateRequest) => {
|
||||
|
||||
const options: RecordListOptions = {
|
||||
sort: "-created",
|
||||
expand: "workflow",
|
||||
expand: "workflowId",
|
||||
requestKey: null,
|
||||
};
|
||||
|
||||
|
@ -17,7 +17,7 @@ export const list = async (request: ListWorkflowRunsRequest) => {
|
||||
return await getPocketBase()
|
||||
.collection(COLLECTION_NAME)
|
||||
.getList<WorkflowRunModel>(page, perPage, {
|
||||
filter: getPocketBase().filter("workflow={:workflowId}", { workflowId: request.workflowId }),
|
||||
filter: getPocketBase().filter("workflowId={:workflowId}", { workflowId: request.workflowId }),
|
||||
sort: "-created",
|
||||
requestKey: null,
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user