diff --git a/cmd/backup/config.go b/cmd/backup/config.go index 42e8a98..680756f 100644 --- a/cmd/backup/config.go +++ b/cmd/backup/config.go @@ -72,6 +72,7 @@ type Config struct { LockTimeout time.Duration `split_words:"true" default:"60m"` AzureStorageAccountName string `split_words:"true"` AzureStoragePrimaryAccountKey string `split_words:"true"` + AzureStorageConnectionString string `split_words:"true"` AzureStorageContainerName string `split_words:"true"` AzureStoragePath string `split_words:"true"` AzureStorageEndpoint string `split_words:"true" default:"https://{{ .AccountName }}.blob.core.windows.net/"` diff --git a/cmd/backup/script.go b/cmd/backup/script.go index 862d478..186f0c0 100644 --- a/cmd/backup/script.go +++ b/cmd/backup/script.go @@ -193,6 +193,7 @@ func (s *script) init() error { PrimaryAccountKey: s.c.AzureStoragePrimaryAccountKey, Endpoint: s.c.AzureStorageEndpoint, RemotePath: s.c.AzureStoragePath, + ConnectionString: s.c.AzureStorageConnectionString, } azureBackend, err := azure.NewStorageBackend(azureConfig, logFunc) if err != nil { diff --git a/docs/reference/index.md b/docs/reference/index.md index 0353b4d..aff09b2 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -245,10 +245,17 @@ You can populate below template according to your requirements and use it as you # AZURE_STORAGE_ACCOUNT_NAME="account-name" # The credential's primary account key when using Azure Blob Storage. If this -# is not given, the command tries to fall back to using a managed identity. +# is not given, the command tries to fall back to using a connection string +# (if given) or a managed identity (if nothing is given). # AZURE_STORAGE_PRIMARY_ACCOUNT_KEY="" +# A connection string for accessing Azure Blob Storage. If this +# is not given, the command tries to fall back to using a primary account key +# (if given) or a managed identity (if nothing is given). + +# AZURE_STORAGE_CONNECTION_STRING="" + # The container name when using Azure Blob Storage. # AZURE_STORAGE_CONTAINER_NAME="container-name" diff --git a/internal/storage/azure/azure.go b/internal/storage/azure/azure.go index 8bc11b0..00d86d4 100644 --- a/internal/storage/azure/azure.go +++ b/internal/storage/azure/azure.go @@ -33,12 +33,17 @@ type Config struct { AccountName string ContainerName string PrimaryAccountKey string + ConnectionString string Endpoint string RemotePath string } // NewStorageBackend creates and initializes a new Azure Blob Storage backend. func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error) { + if opts.PrimaryAccountKey != "" && opts.ConnectionString != "" { + return nil, errwrap.Wrap(nil, "using primary account key and connection string are mutually exclusive") + } + endpointTemplate, err := template.New("endpoint").Parse(opts.Endpoint) if err != nil { return nil, errwrap.Wrap(err, "error parsing endpoint template") @@ -58,7 +63,12 @@ func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error client, err = azblob.NewClientWithSharedKeyCredential(normalizedEndpoint, cred, nil) if err != nil { - return nil, errwrap.Wrap(err, "error creating Azure client") + return nil, errwrap.Wrap(err, "error creating azure client from primary account key") + } + } else if opts.ConnectionString != "" { + client, err = azblob.NewClientFromConnectionString(opts.ConnectionString, nil) + if err != nil { + return nil, errwrap.Wrap(err, "error creating azure client from connection string") } } else { cred, err := azidentity.NewManagedIdentityCredential(nil) @@ -67,7 +77,7 @@ func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error } client, err = azblob.NewClient(normalizedEndpoint, cred, nil) if err != nil { - return nil, errwrap.Wrap(err, "error creating Azure client") + return nil, errwrap.Wrap(err, "error creating azure client from managed identity") } }