feat: v2.0 Sprint 3 - Cloud URI Support & Command Integration (Part 1)

Sprint 3 Implementation - Cloud URI Support:

New Features:
 Cloud URI parser (s3://bucket/path)
 Backup command with --cloud URI flag
 Restore from cloud URIs
 Verify cloud backups
 Cleanup cloud storage with retention policy

New Files:
- internal/cloud/uri.go - Cloud URI parser
- internal/restore/ - Cloud download module
- internal/restore/cloud_download.go - Download & verify helper

Modified Commands:
- cmd/backup.go - Added --cloud s3://bucket/path flag
- cmd/restore.go - Auto-detect & download from cloud URIs
- cmd/verify.go - Verify backups from cloud storage
- cmd/cleanup.go - Apply retention policy to cloud storage

URI Support:
- s3://bucket/path/file.dump - AWS S3
- minio://bucket/path/file.dump - MinIO
- b2://bucket/path/file.dump - Backblaze B2
- gs://bucket/path/file.dump - Google Cloud Storage

Examples:
  # Backup with cloud URI
  dbbackup backup single mydb --cloud s3://my-bucket/backups/

  # Restore from cloud
  dbbackup restore single s3://my-bucket/backups/mydb.dump --confirm

  # Verify cloud backup
  dbbackup verify-backup s3://my-bucket/backups/mydb.dump

  # Cleanup old cloud backups
  dbbackup cleanup s3://my-bucket/backups/ --retention-days 30

Features:
- Automatic download to temp directory
- SHA-256 verification after download
- Automatic temp file cleanup
- Progress tracking for downloads
- Metadata synchronization
- Retention policy for cloud storage

Sprint 3 Part 1 COMPLETE!
This commit is contained in:
2025-11-25 20:30:28 +00:00
parent 20b7f1ec04
commit bdf9af0650
6 changed files with 798 additions and 37 deletions

View File

@@ -3,6 +3,7 @@ package cmd
import (
"fmt"
"dbbackup/internal/cloud"
"github.com/spf13/cobra"
)
@@ -92,6 +93,7 @@ func init() {
// Cloud storage flags for all backup commands
for _, cmd := range []*cobra.Command{clusterCmd, singleCmd, sampleCmd} {
cmd.Flags().String("cloud", "", "Cloud storage URI (e.g., s3://bucket/path) - takes precedence over individual flags")
cmd.Flags().Bool("cloud-auto-upload", false, "Automatically upload backup to cloud after completion")
cmd.Flags().String("cloud-provider", "", "Cloud provider (s3, minio, b2)")
cmd.Flags().String("cloud-bucket", "", "Cloud bucket name")
@@ -109,32 +111,39 @@ func init() {
}
}
// Update cloud config from flags
if c.Flags().Changed("cloud-auto-upload") {
if autoUpload, _ := c.Flags().GetBool("cloud-auto-upload"); autoUpload {
cfg.CloudEnabled = true
cfg.CloudAutoUpload = true
// Check if --cloud URI flag is provided (takes precedence)
if c.Flags().Changed("cloud") {
if err := parseCloudURIFlag(c); err != nil {
return err
}
} else {
// Update cloud config from individual flags
if c.Flags().Changed("cloud-auto-upload") {
if autoUpload, _ := c.Flags().GetBool("cloud-auto-upload"); autoUpload {
cfg.CloudEnabled = true
cfg.CloudAutoUpload = true
}
}
if c.Flags().Changed("cloud-provider") {
cfg.CloudProvider, _ = c.Flags().GetString("cloud-provider")
}
if c.Flags().Changed("cloud-bucket") {
cfg.CloudBucket, _ = c.Flags().GetString("cloud-bucket")
}
if c.Flags().Changed("cloud-region") {
cfg.CloudRegion, _ = c.Flags().GetString("cloud-region")
}
if c.Flags().Changed("cloud-endpoint") {
cfg.CloudEndpoint, _ = c.Flags().GetString("cloud-endpoint")
}
if c.Flags().Changed("cloud-prefix") {
cfg.CloudPrefix, _ = c.Flags().GetString("cloud-prefix")
}
}
if c.Flags().Changed("cloud-provider") {
cfg.CloudProvider, _ = c.Flags().GetString("cloud-provider")
}
if c.Flags().Changed("cloud-bucket") {
cfg.CloudBucket, _ = c.Flags().GetString("cloud-bucket")
}
if c.Flags().Changed("cloud-region") {
cfg.CloudRegion, _ = c.Flags().GetString("cloud-region")
}
if c.Flags().Changed("cloud-endpoint") {
cfg.CloudEndpoint, _ = c.Flags().GetString("cloud-endpoint")
}
if c.Flags().Changed("cloud-prefix") {
cfg.CloudPrefix, _ = c.Flags().GetString("cloud-prefix")
}
return nil
@@ -177,4 +186,40 @@ func init() {
// Mark the strategy flags as mutually exclusive
sampleCmd.MarkFlagsMutuallyExclusive("sample-ratio", "sample-percent", "sample-count")
}
// parseCloudURIFlag parses the --cloud URI flag and updates config
func parseCloudURIFlag(cmd *cobra.Command) error {
cloudURI, _ := cmd.Flags().GetString("cloud")
if cloudURI == "" {
return nil
}
// Parse cloud URI
uri, err := cloud.ParseCloudURI(cloudURI)
if err != nil {
return fmt.Errorf("invalid cloud URI: %w", err)
}
// Enable cloud and auto-upload
cfg.CloudEnabled = true
cfg.CloudAutoUpload = true
// Update config from URI
cfg.CloudProvider = uri.Provider
cfg.CloudBucket = uri.Bucket
if uri.Region != "" {
cfg.CloudRegion = uri.Region
}
if uri.Endpoint != "" {
cfg.CloudEndpoint = uri.Endpoint
}
if uri.Path != "" {
cfg.CloudPrefix = uri.Dir()
}
return nil
}