style(go): 统一后端代码格式

This commit is contained in:
Awuqing
2026-08-09 19:42:15 +08:00
parent 14b61b23a2
commit 4cbd4c302a
14 changed files with 166 additions and 163 deletions
-1
View File
@@ -95,4 +95,3 @@ func redirectStderr(path string) (func(), error) {
_ = f.Close() _ = f.Close()
}, nil }, nil
} }
-1
View File
@@ -357,4 +357,3 @@ func buildStorageRegistry() *storage.Registry {
storageRclone.RegisterAllBackends(registry) storageRclone.RegisterAllBackends(registry)
return registry return registry
} }
+4 -4
View File
@@ -21,10 +21,10 @@ import (
type Function string type Function string
const ( const (
FunctionBackup Function = "backup" FunctionBackup Function = "backup"
FunctionRestore Function = "restore" FunctionRestore Function = "restore"
FunctionInquire Function = "inquire" FunctionInquire Function = "inquire"
FunctionDelete Function = "delete" FunctionDelete Function = "delete"
) )
// BackupRequest 是 BACKUP 操作的单条请求。 // BackupRequest 是 BACKUP 操作的单条请求。
@@ -160,7 +160,7 @@ func TestFileRunnerSelectiveRestore(t *testing.T) {
} }
diffAssertContent(t, filepath.Join(restoreSrc, "a.txt"), "alpha") diffAssertContent(t, filepath.Join(restoreSrc, "a.txt"), "alpha")
diffAssertContent(t, filepath.Join(restoreSrc, "sub", "c.txt"), "charlie") // 选中目录 → 子项一并恢复 diffAssertContent(t, filepath.Join(restoreSrc, "sub", "c.txt"), "charlie") // 选中目录 → 子项一并恢复
diffAssertAbsent(t, filepath.Join(restoreSrc, "b.txt")) // 未选中 → 不恢复 diffAssertAbsent(t, filepath.Join(restoreSrc, "b.txt")) // 未选中 → 不恢复
} }
// TestFileRunnerDifferentialWithoutBaseIsFull 验证无基线时差异请求回退为全量(产出清单、含全部文件)。 // TestFileRunnerDifferentialWithoutBaseIsFull 验证无基线时差异请求回退为全量(产出清单、含全部文件)。
-1
View File
@@ -160,4 +160,3 @@ func formatFileSize(size int64) string {
return fmt.Sprintf("%d B", size) return fmt.Sprintf("%d B", size)
} }
} }
+2 -2
View File
@@ -32,8 +32,8 @@ func writeTestTar(t *testing.T, entries map[string][]byte) string {
func TestVerifyTarArchive_Valid(t *testing.T) { func TestVerifyTarArchive_Valid(t *testing.T) {
path := writeTestTar(t, map[string][]byte{ path := writeTestTar(t, map[string][]byte{
"readme.md": []byte("hello"), "readme.md": []byte("hello"),
"data.bin": []byte("world!!!"), "data.bin": []byte("world!!!"),
}) })
report, err := VerifyTarArchive(path, "") report, err := VerifyTarArchive(path, "")
if err != nil { if err != nil {
+5 -4
View File
@@ -24,10 +24,11 @@ type MaintenanceWindow struct {
// 简化语法:多个窗口以 ';' 分隔,每个窗口按 "[days=xxx;]time=HH:MM-HH:MM" 格式。 // 简化语法:多个窗口以 ';' 分隔,每个窗口按 "[days=xxx;]time=HH:MM-HH:MM" 格式。
// Days 缺省 = 全周;若不合法,跳过该段而非抛错(让调用方尽力工作)。 // Days 缺省 = 全周;若不合法,跳过该段而非抛错(让调用方尽力工作)。
// 示例: // 示例:
// "time=01:00-05:00" 每天 1 点到 5 点 //
// "days=sat,sun;time=00:00-23:59" 仅周末全天 // "time=01:00-05:00" 每天 1 点到 5 点
// "time=22:00-06:00" 每天跨夜 // "days=sat,sun;time=00:00-23:59" 仅周末全天
// "days=mon,tue,wed,thu,fri;time=22:00-06:00" 工作日跨夜 // "time=22:00-06:00" 每天跨夜
// "days=mon,tue,wed,thu,fri;time=22:00-06:00" 工作日跨夜
func ParseMaintenanceWindows(value string) []MaintenanceWindow { func ParseMaintenanceWindows(value string) []MaintenanceWindow {
v := strings.TrimSpace(value) v := strings.TrimSpace(value)
if v == "" { if v == "" {
+11 -11
View File
@@ -6,12 +6,12 @@ import "time"
// 任一 Notification 可订阅多个事件,EventTypes 字段存 CSV。 // 任一 Notification 可订阅多个事件,EventTypes 字段存 CSV。
// 空 EventTypes + OnSuccess/OnFailure=true 时沿用旧语义(仅备份成功/失败)。 // 空 EventTypes + OnSuccess/OnFailure=true 时沿用旧语义(仅备份成功/失败)。
const ( const (
NotificationEventBackupSuccess = "backup_success" NotificationEventBackupSuccess = "backup_success"
NotificationEventBackupFailed = "backup_failed" NotificationEventBackupFailed = "backup_failed"
NotificationEventRestoreSuccess = "restore_success" NotificationEventRestoreSuccess = "restore_success"
NotificationEventRestoreFailed = "restore_failed" NotificationEventRestoreFailed = "restore_failed"
NotificationEventVerifyFailed = "verify_failed" NotificationEventVerifyFailed = "verify_failed"
NotificationEventSLAViolation = "sla_violation" NotificationEventSLAViolation = "sla_violation"
// NotificationEventStorageUnhealthy 存储目标连接失败(后台健康扫描触发)。 // NotificationEventStorageUnhealthy 存储目标连接失败(后台健康扫描触发)。
NotificationEventStorageUnhealthy = "storage_unhealthy" NotificationEventStorageUnhealthy = "storage_unhealthy"
// NotificationEventReplicationFailed 备份复制失败。 // NotificationEventReplicationFailed 备份复制失败。
@@ -23,13 +23,13 @@ const (
) )
type Notification struct { type Notification struct {
ID uint `gorm:"primaryKey" json:"id"` ID uint `gorm:"primaryKey" json:"id"`
Type string `gorm:"size:20;index;not null" json:"type"` Type string `gorm:"size:20;index;not null" json:"type"`
Name string `gorm:"size:100;uniqueIndex;not null" json:"name"` Name string `gorm:"size:100;uniqueIndex;not null" json:"name"`
ConfigCiphertext string `gorm:"column:config_ciphertext;type:text;not null" json:"-"` ConfigCiphertext string `gorm:"column:config_ciphertext;type:text;not null" json:"-"`
Enabled bool `gorm:"not null;default:true" json:"enabled"` Enabled bool `gorm:"not null;default:true" json:"enabled"`
OnSuccess bool `gorm:"column:on_success;not null;default:false" json:"onSuccess"` OnSuccess bool `gorm:"column:on_success;not null;default:false" json:"onSuccess"`
OnFailure bool `gorm:"column:on_failure;not null;default:true" json:"onFailure"` OnFailure bool `gorm:"column:on_failure;not null;default:true" json:"onFailure"`
// EventTypes 逗号分隔,订阅的事件类型。 // EventTypes 逗号分隔,订阅的事件类型。
// 空 = 仅监听备份成功/失败(兼容旧配置);非空则严格按订阅触发。 // 空 = 仅监听备份成功/失败(兼容旧配置);非空则严格按订阅触发。
EventTypes string `gorm:"column:event_types;size:500" json:"eventTypes"` EventTypes string `gorm:"column:event_types;size:500" json:"eventTypes"`
+13 -13
View File
@@ -24,19 +24,19 @@ type ReplicationRecord struct {
SourceTargetID uint `gorm:"column:source_target_id;index;not null" json:"sourceTargetId"` SourceTargetID uint `gorm:"column:source_target_id;index;not null" json:"sourceTargetId"`
SourceTarget StorageTarget `gorm:"foreignKey:SourceTargetID;references:ID" json:"sourceTarget,omitempty"` SourceTarget StorageTarget `gorm:"foreignKey:SourceTargetID;references:ID" json:"sourceTarget,omitempty"`
// DestTargetID 目标存储(复制过去) // DestTargetID 目标存储(复制过去)
DestTargetID uint `gorm:"column:dest_target_id;index;not null" json:"destTargetId"` DestTargetID uint `gorm:"column:dest_target_id;index;not null" json:"destTargetId"`
DestTarget StorageTarget `gorm:"foreignKey:DestTargetID;references:ID" json:"destTarget,omitempty"` DestTarget StorageTarget `gorm:"foreignKey:DestTargetID;references:ID" json:"destTarget,omitempty"`
Status string `gorm:"size:20;index;not null" json:"status"` Status string `gorm:"size:20;index;not null" json:"status"`
StoragePath string `gorm:"column:storage_path;size:500" json:"storagePath"` StoragePath string `gorm:"column:storage_path;size:500" json:"storagePath"`
FileSize int64 `gorm:"column:file_size;not null;default:0" json:"fileSize"` FileSize int64 `gorm:"column:file_size;not null;default:0" json:"fileSize"`
Checksum string `gorm:"column:checksum;size:64" json:"checksum"` Checksum string `gorm:"column:checksum;size:64" json:"checksum"`
ErrorMessage string `gorm:"column:error_message;size:2000" json:"errorMessage"` ErrorMessage string `gorm:"column:error_message;size:2000" json:"errorMessage"`
DurationSeconds int `gorm:"column:duration_seconds;not null;default:0" json:"durationSeconds"` DurationSeconds int `gorm:"column:duration_seconds;not null;default:0" json:"durationSeconds"`
TriggeredBy string `gorm:"column:triggered_by;size:100" json:"triggeredBy"` TriggeredBy string `gorm:"column:triggered_by;size:100" json:"triggeredBy"`
StartedAt time.Time `gorm:"column:started_at;index;not null" json:"startedAt"` StartedAt time.Time `gorm:"column:started_at;index;not null" json:"startedAt"`
CompletedAt *time.Time `gorm:"column:completed_at;index" json:"completedAt,omitempty"` CompletedAt *time.Time `gorm:"column:completed_at;index" json:"completedAt,omitempty"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"` UpdatedAt time.Time `json:"updatedAt"`
} }
func (ReplicationRecord) TableName() string { func (ReplicationRecord) TableName() string {
+4 -4
View File
@@ -11,10 +11,10 @@ import "time"
// - name // - name
// - sourcePath / sourcePaths 中的 {{.Host}} / {{.Env}} 等占位符 // - sourcePath / sourcePaths 中的 {{.Host}} / {{.Env}} 等占位符
type TaskTemplate struct { type TaskTemplate struct {
ID uint `gorm:"primaryKey" json:"id"` ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"size:128;uniqueIndex;not null" json:"name"` Name string `gorm:"size:128;uniqueIndex;not null" json:"name"`
Description string `gorm:"size:500" json:"description"` Description string `gorm:"size:500" json:"description"`
TaskType string `gorm:"column:task_type;size:20;not null" json:"taskType"` TaskType string `gorm:"column:task_type;size:20;not null" json:"taskType"`
// Payload JSON,存完整 BackupTaskUpsertInput 的序列化 // Payload JSON,存完整 BackupTaskUpsertInput 的序列化
Payload string `gorm:"type:text;not null" json:"payload"` Payload string `gorm:"type:text;not null" json:"payload"`
CreatedBy string `gorm:"column:created_by;size:128" json:"createdBy"` CreatedBy string `gorm:"column:created_by;size:128" json:"createdBy"`
+20 -20
View File
@@ -126,14 +126,14 @@ func (s *DashboardService) Timeline(ctx context.Context, days int) ([]repository
// 判定规则:任务设置了 SLAHoursRPO > 0,且距最近一次 success 备份的时间 > SLAHoursRPO。 // 判定规则:任务设置了 SLAHoursRPO > 0,且距最近一次 success 备份的时间 > SLAHoursRPO。
// 从未成功过的任务(LastSuccessAt = nil)若启用也视为违约(from createdAt 起算)。 // 从未成功过的任务(LastSuccessAt = nil)若启用也视为违约(from createdAt 起算)。
type SLAViolation struct { type SLAViolation struct {
TaskID uint `json:"taskId"` TaskID uint `json:"taskId"`
TaskName string `json:"taskName"` TaskName string `json:"taskName"`
NodeID uint `json:"nodeId"` NodeID uint `json:"nodeId"`
NodeName string `json:"nodeName,omitempty"` NodeName string `json:"nodeName,omitempty"`
SLAHoursRPO int `json:"slaHoursRpo"` SLAHoursRPO int `json:"slaHoursRpo"`
LastSuccessAt *time.Time `json:"lastSuccessAt,omitempty"` LastSuccessAt *time.Time `json:"lastSuccessAt,omitempty"`
HoursSinceLastSuccess float64 `json:"hoursSinceLastSuccess"` HoursSinceLastSuccess float64 `json:"hoursSinceLastSuccess"`
NeverSucceeded bool `json:"neverSucceeded"` NeverSucceeded bool `json:"neverSucceeded"`
} }
// SLAComplianceReport Dashboard 的 SLA 合规概览。 // SLAComplianceReport Dashboard 的 SLA 合规概览。
@@ -204,15 +204,15 @@ func roundHours(value float64) float64 {
// ClusterNodeSummary 集群节点简报(Dashboard 用)。 // ClusterNodeSummary 集群节点简报(Dashboard 用)。
type ClusterNodeSummary struct { type ClusterNodeSummary struct {
ID uint `json:"id"` ID uint `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
Status string `json:"status"` Status string `json:"status"`
IsLocal bool `json:"isLocal"` IsLocal bool `json:"isLocal"`
AgentVersion string `json:"agentVersion"` AgentVersion string `json:"agentVersion"`
VersionStatus string `json:"versionStatus"` // current | outdated | unknown VersionStatus string `json:"versionStatus"` // current | outdated | unknown
LastSeen time.Time `json:"lastSeen"` LastSeen time.Time `json:"lastSeen"`
TaskCount int64 `json:"taskCount"` TaskCount int64 `json:"taskCount"`
} }
// ClusterOverview Dashboard 集群概览卡片。 // ClusterOverview Dashboard 集群概览卡片。
@@ -312,9 +312,9 @@ func (s *DashboardService) Breakdown(ctx context.Context, days int) (*BreakdownS
} }
} }
result := &BreakdownStats{ result := &BreakdownStats{
ByType: makeBreakdown(typeCounts, typeLabel), ByType: makeBreakdown(typeCounts, typeLabel),
ByNode: makeBreakdownByUint(nodeCounts, nodeNames, "节点 #"), ByNode: makeBreakdownByUint(nodeCounts, nodeNames, "节点 #"),
ByStatus: []BreakdownItem{}, ByStatus: []BreakdownItem{},
ByStorage: []BreakdownItem{}, ByStorage: []BreakdownItem{},
} }
// 按状态(最近 days 天记录) // 按状态(最近 days 天记录)
+5 -6
View File
@@ -74,11 +74,11 @@ func (s *SystemService) CheckUpdate(ctx context.Context) (*UpdateCheckResult, er
} }
var release struct { var release struct {
TagName string `json:"tag_name"` TagName string `json:"tag_name"`
HTMLURL string `json:"html_url"` HTMLURL string `json:"html_url"`
Body string `json:"body"` Body string `json:"body"`
Published string `json:"published_at"` Published string `json:"published_at"`
Assets []struct { Assets []struct {
Name string `json:"name"` Name string `json:"name"`
BrowserDownloadURL string `json:"browser_download_url"` BrowserDownloadURL string `json:"browser_download_url"`
} `json:"assets"` } `json:"assets"`
@@ -132,4 +132,3 @@ func (s *SystemService) GetInfo(_ context.Context) *SystemInfo {
} }
return info return info
} }
+85 -85
View File
@@ -14,9 +14,9 @@ import (
// TaskExportService 管理备份任务的 JSON 导入 / 导出。 // TaskExportService 管理备份任务的 JSON 导入 / 导出。
// 用途: // 用途:
// 1. 集群迁移(旧 Master → 新 Master 的任务配置搬迁) // 1. 集群迁移(旧 Master → 新 Master 的任务配置搬迁)
// 2. 灾备恢复(任务配置本地文件化,Master 宕机后重建) // 2. 灾备恢复(任务配置本地文件化,Master 宕机后重建)
// 3. 配置审计(版本化 Git 管理 JSON 快照) // 3. 配置审计(版本化 Git 管理 JSON 快照)
// //
// 出于安全考虑,导出/导入不包含任何敏感字段: // 出于安全考虑,导出/导入不包含任何敏感字段:
// - 数据库密码(DBPasswordCiphertext):跳过,导入后需人工填补 // - 数据库密码(DBPasswordCiphertext):跳过,导入后需人工填补
@@ -40,35 +40,35 @@ func NewTaskExportService(
// ExportedTask 导出格式:按名称引用存储/节点,不含敏感数据。 // ExportedTask 导出格式:按名称引用存储/节点,不含敏感数据。
type ExportedTask struct { type ExportedTask struct {
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` Type string `json:"type"`
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
CronExpr string `json:"cronExpr,omitempty"` CronExpr string `json:"cronExpr,omitempty"`
SourcePath string `json:"sourcePath,omitempty"` SourcePath string `json:"sourcePath,omitempty"`
SourcePaths []string `json:"sourcePaths,omitempty"` SourcePaths []string `json:"sourcePaths,omitempty"`
ExcludePatterns []string `json:"excludePatterns,omitempty"` ExcludePatterns []string `json:"excludePatterns,omitempty"`
DBHost string `json:"dbHost,omitempty"` DBHost string `json:"dbHost,omitempty"`
DBPort int `json:"dbPort,omitempty"` DBPort int `json:"dbPort,omitempty"`
DBUser string `json:"dbUser,omitempty"` DBUser string `json:"dbUser,omitempty"`
DBName string `json:"dbName,omitempty"` DBName string `json:"dbName,omitempty"`
DBPath string `json:"dbPath,omitempty"` DBPath string `json:"dbPath,omitempty"`
ExtraConfig map[string]any `json:"extraConfig,omitempty"` ExtraConfig map[string]any `json:"extraConfig,omitempty"`
// 按名称引用:导入时按名称查找对应 ID // 按名称引用:导入时按名称查找对应 ID
StorageTargetNames []string `json:"storageTargetNames"` StorageTargetNames []string `json:"storageTargetNames"`
ReplicationTargetNames []string `json:"replicationTargetNames,omitempty"` ReplicationTargetNames []string `json:"replicationTargetNames,omitempty"`
NodeName string `json:"nodeName,omitempty"` NodeName string `json:"nodeName,omitempty"`
DependsOnTaskNames []string `json:"dependsOnTaskNames,omitempty"` DependsOnTaskNames []string `json:"dependsOnTaskNames,omitempty"`
Tags string `json:"tags,omitempty"` Tags string `json:"tags,omitempty"`
Compression string `json:"compression,omitempty"` Compression string `json:"compression,omitempty"`
Encrypt bool `json:"encrypt,omitempty"` Encrypt bool `json:"encrypt,omitempty"`
RetentionDays int `json:"retentionDays,omitempty"` RetentionDays int `json:"retentionDays,omitempty"`
MaxBackups int `json:"maxBackups,omitempty"` MaxBackups int `json:"maxBackups,omitempty"`
VerifyEnabled bool `json:"verifyEnabled,omitempty"` VerifyEnabled bool `json:"verifyEnabled,omitempty"`
VerifyCronExpr string `json:"verifyCronExpr,omitempty"` VerifyCronExpr string `json:"verifyCronExpr,omitempty"`
VerifyMode string `json:"verifyMode,omitempty"` VerifyMode string `json:"verifyMode,omitempty"`
SLAHoursRPO int `json:"slaHoursRpo,omitempty"` SLAHoursRPO int `json:"slaHoursRpo,omitempty"`
AlertOnConsecutiveFails int `json:"alertOnConsecutiveFails,omitempty"` AlertOnConsecutiveFails int `json:"alertOnConsecutiveFails,omitempty"`
MaintenanceWindows string `json:"maintenanceWindows,omitempty"` MaintenanceWindows string `json:"maintenanceWindows,omitempty"`
} }
// ExportPayload 导出整体结构,带元信息。 // ExportPayload 导出整体结构,带元信息。
@@ -233,67 +233,67 @@ func (s *TaskExportService) toExported(item *model.BackupTask, targetNames, node
nodeName = nodeNames[item.NodeID] nodeName = nodeNames[item.NodeID]
} }
return ExportedTask{ return ExportedTask{
Name: item.Name, Name: item.Name,
Type: item.Type, Type: item.Type,
Enabled: item.Enabled, Enabled: item.Enabled,
CronExpr: item.CronExpr, CronExpr: item.CronExpr,
SourcePath: item.SourcePath, SourcePath: item.SourcePath,
SourcePaths: sourcePaths, SourcePaths: sourcePaths,
ExcludePatterns: excludes, ExcludePatterns: excludes,
DBHost: item.DBHost, DBHost: item.DBHost,
DBPort: item.DBPort, DBPort: item.DBPort,
DBUser: item.DBUser, DBUser: item.DBUser,
DBName: item.DBName, DBName: item.DBName,
DBPath: item.DBPath, DBPath: item.DBPath,
ExtraConfig: extra, ExtraConfig: extra,
StorageTargetNames: storageNames, StorageTargetNames: storageNames,
ReplicationTargetNames: replicationNames, ReplicationTargetNames: replicationNames,
NodeName: nodeName, NodeName: nodeName,
DependsOnTaskNames: dependsOnNames, DependsOnTaskNames: dependsOnNames,
Tags: item.Tags, Tags: item.Tags,
Compression: item.Compression, Compression: item.Compression,
Encrypt: item.Encrypt, Encrypt: item.Encrypt,
RetentionDays: item.RetentionDays, RetentionDays: item.RetentionDays,
MaxBackups: item.MaxBackups, MaxBackups: item.MaxBackups,
VerifyEnabled: item.VerifyEnabled, VerifyEnabled: item.VerifyEnabled,
VerifyCronExpr: item.VerifyCronExpr, VerifyCronExpr: item.VerifyCronExpr,
VerifyMode: item.VerifyMode, VerifyMode: item.VerifyMode,
SLAHoursRPO: item.SLAHoursRPO, SLAHoursRPO: item.SLAHoursRPO,
AlertOnConsecutiveFails: item.AlertOnConsecutiveFails, AlertOnConsecutiveFails: item.AlertOnConsecutiveFails,
MaintenanceWindows: item.MaintenanceWindows, MaintenanceWindows: item.MaintenanceWindows,
} }
} }
func (s *TaskExportService) toUpsertInput(t ExportedTask, targetsByName, nodesByName map[string]uint, deps []uint) BackupTaskUpsertInput { func (s *TaskExportService) toUpsertInput(t ExportedTask, targetsByName, nodesByName map[string]uint, deps []uint) BackupTaskUpsertInput {
return BackupTaskUpsertInput{ return BackupTaskUpsertInput{
Name: t.Name, Name: t.Name,
Type: t.Type, Type: t.Type,
Enabled: t.Enabled, Enabled: t.Enabled,
CronExpr: t.CronExpr, CronExpr: t.CronExpr,
SourcePath: t.SourcePath, SourcePath: t.SourcePath,
SourcePaths: t.SourcePaths, SourcePaths: t.SourcePaths,
ExcludePatterns: t.ExcludePatterns, ExcludePatterns: t.ExcludePatterns,
DBHost: t.DBHost, DBHost: t.DBHost,
DBPort: t.DBPort, DBPort: t.DBPort,
DBUser: t.DBUser, DBUser: t.DBUser,
DBName: t.DBName, DBName: t.DBName,
DBPath: t.DBPath, DBPath: t.DBPath,
ExtraConfig: t.ExtraConfig, ExtraConfig: t.ExtraConfig,
StorageTargetIDs: idsFromNames(t.StorageTargetNames, targetsByName), StorageTargetIDs: idsFromNames(t.StorageTargetNames, targetsByName),
ReplicationTargetIDs: idsFromNames(t.ReplicationTargetNames, targetsByName), ReplicationTargetIDs: idsFromNames(t.ReplicationTargetNames, targetsByName),
NodeID: nodesByName[t.NodeName], NodeID: nodesByName[t.NodeName],
Tags: t.Tags, Tags: t.Tags,
Compression: t.Compression, Compression: t.Compression,
Encrypt: t.Encrypt, Encrypt: t.Encrypt,
RetentionDays: t.RetentionDays, RetentionDays: t.RetentionDays,
MaxBackups: t.MaxBackups, MaxBackups: t.MaxBackups,
VerifyEnabled: t.VerifyEnabled, VerifyEnabled: t.VerifyEnabled,
VerifyCronExpr: t.VerifyCronExpr, VerifyCronExpr: t.VerifyCronExpr,
VerifyMode: t.VerifyMode, VerifyMode: t.VerifyMode,
SLAHoursRPO: t.SLAHoursRPO, SLAHoursRPO: t.SLAHoursRPO,
AlertOnConsecutiveFails: t.AlertOnConsecutiveFails, AlertOnConsecutiveFails: t.AlertOnConsecutiveFails,
MaintenanceWindows: t.MaintenanceWindows, MaintenanceWindows: t.MaintenanceWindows,
DependsOnTaskIDs: deps, DependsOnTaskIDs: deps,
} }
} }
+16 -10
View File
@@ -43,7 +43,7 @@ type LocalDiskFactory struct{}
func NewLocalDiskFactory() LocalDiskFactory { return LocalDiskFactory{} } func NewLocalDiskFactory() LocalDiskFactory { return LocalDiskFactory{} }
func (LocalDiskFactory) Type() storage.ProviderType { return storage.ProviderTypeLocalDisk } func (LocalDiskFactory) Type() storage.ProviderType { return storage.ProviderTypeLocalDisk }
func (LocalDiskFactory) SensitiveFields() []string { return nil } func (LocalDiskFactory) SensitiveFields() []string { return nil }
func (LocalDiskFactory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) { func (LocalDiskFactory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) {
cfg, err := storage.DecodeConfig[storage.LocalDiskConfig](rawConfig) cfg, err := storage.DecodeConfig[storage.LocalDiskConfig](rawConfig)
@@ -66,7 +66,7 @@ type S3Factory struct{}
func NewS3Factory() S3Factory { return S3Factory{} } func NewS3Factory() S3Factory { return S3Factory{} }
func (S3Factory) Type() storage.ProviderType { return storage.ProviderTypeS3 } func (S3Factory) Type() storage.ProviderType { return storage.ProviderTypeS3 }
func (S3Factory) SensitiveFields() []string { return []string{"accessKeyId", "secretAccessKey"} } func (S3Factory) SensitiveFields() []string { return []string{"accessKeyId", "secretAccessKey"} }
func (S3Factory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) { func (S3Factory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) {
cfg, err := storage.DecodeConfig[storage.S3Config](rawConfig) cfg, err := storage.DecodeConfig[storage.S3Config](rawConfig)
@@ -116,7 +116,7 @@ type WebDAVFactory struct{}
func NewWebDAVFactory() WebDAVFactory { return WebDAVFactory{} } func NewWebDAVFactory() WebDAVFactory { return WebDAVFactory{} }
func (WebDAVFactory) Type() storage.ProviderType { return storage.ProviderTypeWebDAV } func (WebDAVFactory) Type() storage.ProviderType { return storage.ProviderTypeWebDAV }
func (WebDAVFactory) SensitiveFields() []string { return []string{"username", "password"} } func (WebDAVFactory) SensitiveFields() []string { return []string{"username", "password"} }
func (WebDAVFactory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) { func (WebDAVFactory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) {
cfg, err := storage.DecodeConfig[storage.WebDAVConfig](rawConfig) cfg, err := storage.DecodeConfig[storage.WebDAVConfig](rawConfig)
@@ -187,7 +187,7 @@ type FTPFactory struct{}
func NewFTPFactory() FTPFactory { return FTPFactory{} } func NewFTPFactory() FTPFactory { return FTPFactory{} }
func (FTPFactory) Type() storage.ProviderType { return storage.ProviderTypeFTP } func (FTPFactory) Type() storage.ProviderType { return storage.ProviderTypeFTP }
func (FTPFactory) SensitiveFields() []string { return []string{"username", "password"} } func (FTPFactory) SensitiveFields() []string { return []string{"username", "password"} }
func (FTPFactory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) { func (FTPFactory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) {
cfg, err := storage.DecodeConfig[storage.FTPConfig](rawConfig) cfg, err := storage.DecodeConfig[storage.FTPConfig](rawConfig)
@@ -228,7 +228,7 @@ type AliyunOSSFactory struct{}
func NewAliyunOSSFactory() AliyunOSSFactory { return AliyunOSSFactory{} } func NewAliyunOSSFactory() AliyunOSSFactory { return AliyunOSSFactory{} }
func (AliyunOSSFactory) Type() storage.ProviderType { return storage.ProviderTypeAliyunOSS } func (AliyunOSSFactory) Type() storage.ProviderType { return storage.ProviderTypeAliyunOSS }
func (AliyunOSSFactory) SensitiveFields() []string { return []string{"accessKeyId", "secretAccessKey"} } func (AliyunOSSFactory) SensitiveFields() []string { return []string{"accessKeyId", "secretAccessKey"} }
// AliyunConfig 是阿里云 OSS 的用户配置。 // AliyunConfig 是阿里云 OSS 的用户配置。
type AliyunConfig struct { type AliyunConfig struct {
@@ -269,7 +269,9 @@ type TencentCOSFactory struct{}
func NewTencentCOSFactory() TencentCOSFactory { return TencentCOSFactory{} } func NewTencentCOSFactory() TencentCOSFactory { return TencentCOSFactory{} }
func (TencentCOSFactory) Type() storage.ProviderType { return storage.ProviderTypeTencentCOS } func (TencentCOSFactory) Type() storage.ProviderType { return storage.ProviderTypeTencentCOS }
func (TencentCOSFactory) SensitiveFields() []string { return []string{"accessKeyId", "secretAccessKey"} } func (TencentCOSFactory) SensitiveFields() []string {
return []string{"accessKeyId", "secretAccessKey"}
}
// TencentConfig 是腾讯云 COS 的用户配置。 // TencentConfig 是腾讯云 COS 的用户配置。
type TencentConfig struct { type TencentConfig struct {
@@ -305,7 +307,7 @@ type QiniuKodoFactory struct{}
func NewQiniuKodoFactory() QiniuKodoFactory { return QiniuKodoFactory{} } func NewQiniuKodoFactory() QiniuKodoFactory { return QiniuKodoFactory{} }
func (QiniuKodoFactory) Type() storage.ProviderType { return storage.ProviderTypeQiniuKodo } func (QiniuKodoFactory) Type() storage.ProviderType { return storage.ProviderTypeQiniuKodo }
func (QiniuKodoFactory) SensitiveFields() []string { return []string{"accessKeyId", "secretAccessKey"} } func (QiniuKodoFactory) SensitiveFields() []string { return []string{"accessKeyId", "secretAccessKey"} }
// QiniuConfig 是七牛云 Kodo 的用户配置。 // QiniuConfig 是七牛云 Kodo 的用户配置。
type QiniuConfig struct { type QiniuConfig struct {
@@ -355,7 +357,9 @@ type RcloneFactory struct{}
func NewRcloneFactory() RcloneFactory { return RcloneFactory{} } func NewRcloneFactory() RcloneFactory { return RcloneFactory{} }
func (RcloneFactory) Type() storage.ProviderType { return storage.ProviderTypeRclone } func (RcloneFactory) Type() storage.ProviderType { return storage.ProviderTypeRclone }
func (RcloneFactory) SensitiveFields() []string { return []string{"pass", "password", "secret_access_key", "client_secret", "token"} } func (RcloneFactory) SensitiveFields() []string {
return []string{"pass", "password", "secret_access_key", "client_secret", "token"}
}
func (RcloneFactory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) { func (RcloneFactory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) {
backend, _ := rawConfig["backend"].(string) backend, _ := rawConfig["backend"].(string)
@@ -462,8 +466,10 @@ func NewBackendFactory(backendType string) GenericBackendFactory {
return GenericBackendFactory{backendType: backendType, sensitive: sensitive} return GenericBackendFactory{backendType: backendType, sensitive: sensitive}
} }
func (f GenericBackendFactory) Type() storage.ProviderType { return storage.ProviderType(f.backendType) } func (f GenericBackendFactory) Type() storage.ProviderType {
func (f GenericBackendFactory) SensitiveFields() []string { return f.sensitive } return storage.ProviderType(f.backendType)
}
func (f GenericBackendFactory) SensitiveFields() []string { return f.sensitive }
func (f GenericBackendFactory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) { func (f GenericBackendFactory) New(ctx context.Context, rawConfig map[string]any) (storage.StorageProvider, error) {
root, _ := rawConfig["root"].(string) root, _ := rawConfig["root"].(string)