mirror of
https://github.com/jkaninda/go-storage.git
synced 2026-03-11 12:09:06 +01:00
feat: add gsc and go_storage package
This commit is contained in:
155
azure.go
Normal file
155
azure.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package go_storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
||||
)
|
||||
|
||||
// AzureStorage implements Storage interface for Azure Blob Storage.
|
||||
type AzureStorage struct {
|
||||
client *azblob.Client
|
||||
container string
|
||||
}
|
||||
|
||||
// NewAzureStorage creates a new Azure Blob Storage instance.
|
||||
func NewAzureStorage(config Config) (*AzureStorage, error) {
|
||||
if err := validateConfig(config, map[string]string{
|
||||
"container": config.AzureContainer,
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("azure: %w", err)
|
||||
}
|
||||
|
||||
// Try to get credentials from environment if not provided
|
||||
account := config.AzureAccount
|
||||
if account == "" {
|
||||
account = os.Getenv("AZURE_STORAGE_ACCOUNT")
|
||||
}
|
||||
|
||||
key := config.AzureKey
|
||||
if key == "" {
|
||||
key = os.Getenv("AZURE_STORAGE_KEY")
|
||||
}
|
||||
|
||||
endpoint := config.AzureEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = "blob.core.windows.net"
|
||||
}
|
||||
|
||||
var client *azblob.Client
|
||||
var err error
|
||||
|
||||
if account == "" {
|
||||
// Anonymous access
|
||||
client, err = azblob.NewClientWithNoCredential(endpoint, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("azure: failed to create anonymous client: %w", err)
|
||||
}
|
||||
} else {
|
||||
// Authenticated access
|
||||
credential, err := azblob.NewSharedKeyCredential(account, key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("azure: failed to create credentials: %w", err)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("https://%s.%s", account, endpoint)
|
||||
|
||||
client, err = azblob.NewClientWithSharedKeyCredential(url, credential, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("azure: failed to create client: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return &AzureStorage{
|
||||
client: client,
|
||||
container: config.AzureContainer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Upload uploads a file to Azure Blob Storage.
|
||||
func (a *AzureStorage) Upload(ctx context.Context, localPath string, remotePath string) error {
|
||||
file, err := os.Open(localPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("azure: failed to open local file: %w", err)
|
||||
}
|
||||
defer func(file *os.File) {
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
fmt.Printf("azure: failed to close file: %v\n", err)
|
||||
}
|
||||
}(file)
|
||||
|
||||
_, err = a.client.UploadFile(ctx, a.container, normalizePathSeparators(remotePath), file, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("azure: failed to upload to container %s: %w", a.container, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Download downloads a file from Azure Blob Storage.
|
||||
func (a *AzureStorage) Download(ctx context.Context, remotePath string, localPath string) error {
|
||||
file, err := os.Create(localPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("azure: failed to create local file: %w", err)
|
||||
}
|
||||
defer func(file *os.File) {
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
fmt.Printf("azure: failed to close file: %v\n", err)
|
||||
}
|
||||
}(file)
|
||||
|
||||
_, err = a.client.DownloadFile(ctx, a.container, normalizePathSeparators(remotePath), file, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("azure: failed to download from container %s: %w", a.container, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// List lists blobs in Azure Blob Storage with the given prefix.
|
||||
func (a *AzureStorage) List(ctx context.Context, prefix string) ([]Item, error) {
|
||||
normalizedPrefix := normalizePathSeparators(prefix)
|
||||
|
||||
pager := a.client.NewListBlobsFlatPager(a.container, &azblob.ListBlobsFlatOptions{
|
||||
Prefix: &normalizedPrefix,
|
||||
})
|
||||
|
||||
items := make([]Item, 0)
|
||||
|
||||
for pager.More() {
|
||||
resp, err := pager.NextPage(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("azure: failed to list blobs in container %s: %w", a.container, err)
|
||||
}
|
||||
|
||||
for _, blob := range resp.Segment.BlobItems {
|
||||
items = append(items, Item{
|
||||
Key: *blob.Name,
|
||||
ModifiedTime: *blob.Properties.LastModified,
|
||||
Size: *blob.Properties.ContentLength,
|
||||
IsDirectory: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
// Remove deletes a blob from Azure Blob Storage.
|
||||
func (a *AzureStorage) Remove(ctx context.Context, remotePath string) error {
|
||||
_, err := a.client.DeleteBlob(ctx, a.container, normalizePathSeparators(remotePath), nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("azure: failed to remove blob from container %s: %w", a.container, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close releases resources.
|
||||
func (a *AzureStorage) Close() error {
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user