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