mirror of
https://github.com/jkaninda/go-storage.git
synced 2026-03-10 11:39:02 +01:00
feat: add gsc and go_storage package
This commit is contained in:
140
storage.go
Normal file
140
storage.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package go_storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Storage defines the interface for remote file storage operations.
|
||||
// All implementations must be safe for concurrent use.
|
||||
type Storage interface {
|
||||
// Upload uploads a local file to the remote storage with the given target name.
|
||||
Upload(ctx context.Context, localPath string, remotePath string) error
|
||||
|
||||
// Download downloads a file from remote storage to a local path.
|
||||
Download(ctx context.Context, remotePath string, localPath string) error
|
||||
|
||||
// List returns all items in the storage that match the given prefix.
|
||||
List(ctx context.Context, prefix string) ([]Item, error)
|
||||
|
||||
// Remove deletes a file from remote storage.
|
||||
Remove(ctx context.Context, remotePath string) error
|
||||
|
||||
// Close releases any resources held by the storage implementation.
|
||||
Close() error
|
||||
}
|
||||
|
||||
// Item represents a file or directory in remote storage.
|
||||
type Item struct {
|
||||
Key string // The path/key of the item
|
||||
ModifiedTime time.Time // Last modification time
|
||||
Size int64 // Size in bytes (0 for directories)
|
||||
IsDirectory bool // Whether this item is a directory
|
||||
}
|
||||
|
||||
// Config holds configuration options for creating storage instances.
|
||||
type Config struct {
|
||||
// S3 configuration
|
||||
S3Region string
|
||||
S3Bucket string
|
||||
S3Profile string
|
||||
S3KeyID string
|
||||
S3Secret string
|
||||
S3Endpoint string
|
||||
S3ForcePath bool
|
||||
S3DisableTLS bool
|
||||
|
||||
// B2 configuration
|
||||
B2KeyID string
|
||||
B2AppKey string
|
||||
B2Bucket string
|
||||
B2ConcurrentConnections int
|
||||
B2ForcePath bool
|
||||
|
||||
// Google Cloud Storage configuration
|
||||
GCSBucket string
|
||||
GCSEndpoint string
|
||||
GCSCredentialsFile string
|
||||
|
||||
// Azure configuration
|
||||
AzureAccount string
|
||||
AzureKey string
|
||||
AzureContainer string
|
||||
AzureEndpoint string
|
||||
|
||||
// SFTP configuration
|
||||
SFTPHost string
|
||||
SFTPPort string
|
||||
SFTPUsername string
|
||||
SFTPPassword string
|
||||
SFTPDirectory string
|
||||
SFTPIdentityFile string
|
||||
SFTPIgnoreKnownHosts bool
|
||||
|
||||
// FTP configuration
|
||||
FTPHost string
|
||||
FTPPort string
|
||||
FTPUsername string
|
||||
FTPPassword string
|
||||
FTPDirectory string
|
||||
}
|
||||
|
||||
// StorageType represents the type of storage backend.
|
||||
type StorageType string
|
||||
|
||||
const (
|
||||
StorageTypeS3 StorageType = "s3"
|
||||
StorageTypeGCS StorageType = "gcs"
|
||||
StorageTypeAzure StorageType = "azure"
|
||||
StorageTypeSFTP StorageType = "sftp"
|
||||
StorageTypeFTP StorageType = "ftp"
|
||||
StorageTypeLocal StorageType = "local"
|
||||
)
|
||||
|
||||
// NewStorage creates a new Storage instance based on the specified type and configuration.
|
||||
func NewStorage(storageType StorageType, config Config) (Storage, error) {
|
||||
switch storageType {
|
||||
case StorageTypeS3:
|
||||
return NewS3Storage(config)
|
||||
case StorageTypeGCS:
|
||||
return NewGCSStorage(config)
|
||||
case StorageTypeAzure:
|
||||
return NewAzureStorage(config)
|
||||
case StorageTypeSFTP:
|
||||
return NewSFTPStorage(config)
|
||||
case StorageTypeFTP:
|
||||
return NewFTPStorage(config)
|
||||
case StorageTypeLocal:
|
||||
return NewLocalStorage("/backups")
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported storage type: %s", storageType)
|
||||
}
|
||||
}
|
||||
|
||||
// normalizePathSeparators converts OS-specific path separators to forward slashes.
|
||||
// This is necessary for cloud storage services which expect forward slashes.
|
||||
func normalizePathSeparators(path string) string {
|
||||
if os.PathSeparator == '/' {
|
||||
return path
|
||||
}
|
||||
return strings.ReplaceAll(path, string(os.PathSeparator), "/")
|
||||
}
|
||||
|
||||
// validateConfig checks if the required configuration fields are present.
|
||||
func validateConfig(_ Config, requiredFields map[string]string) error {
|
||||
var missing []string
|
||||
for field, value := range requiredFields {
|
||||
if value == "" {
|
||||
missing = append(missing, field)
|
||||
}
|
||||
}
|
||||
|
||||
if len(missing) > 0 {
|
||||
return fmt.Errorf("missing required configuration: %s", strings.Join(missing, ", "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user