azureblob: add connection string and SAS URL auth - fixes #2118

This commit is contained in:
Nick Craig-Wood 2018-03-24 14:01:23 +00:00
parent 8c0335a176
commit b062ae9d13

View File

@ -10,6 +10,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"net/url"
"path" "path"
"regexp" "regexp"
"strconv" "strconv"
@ -59,10 +60,16 @@ func init() {
NewFs: NewFs, NewFs: NewFs,
Options: []fs.Option{{ Options: []fs.Option{{
Name: "account", Name: "account",
Help: "Storage Account Name", Help: "Storage Account Name (leave blank to use connection string or SAS URL)",
}, { }, {
Name: "key", Name: "key",
Help: "Storage Account Key", Help: "Storage Account Key (leave blank to use connection string or SAS URL)",
}, {
Name: "connection_string",
Help: "Connection string (leave blank if using account/key or SAS URL)",
}, {
Name: "sas_url",
Help: "SAS URL for container level access only\n(leave blank if using account/key or connection string)",
}, { }, {
Name: "endpoint", Name: "endpoint",
Help: "Endpoint for the service - leave blank normally.", Help: "Endpoint for the service - leave blank normally.",
@ -79,7 +86,6 @@ type Fs struct {
root string // the path we are working on if any root string // the path we are working on if any
features *fs.Features // optional features features *fs.Features // optional features
account string // account name account string // account name
key []byte // auth key
endpoint string // name of the starting api endpoint endpoint string // name of the starting api endpoint
bc *storage.BlobStorageClient bc *storage.BlobStorageClient
cc *storage.Container cc *storage.Container
@ -183,36 +189,54 @@ func NewFs(name, root string) (fs.Fs, error) {
return nil, err return nil, err
} }
account := config.FileGet(name, "account") account := config.FileGet(name, "account")
if account == "" {
return nil, errors.New("account not found")
}
key := config.FileGet(name, "key") key := config.FileGet(name, "key")
if key == "" { connectionString := config.FileGet(name, "connection_string")
return nil, errors.New("key not found") sasURL := config.FileGet(name, "sas_url")
}
keyBytes, err := base64.StdEncoding.DecodeString(key)
if err != nil {
return nil, errors.Errorf("malformed storage account key: %v", err)
}
endpoint := config.FileGet(name, "endpoint", storage.DefaultBaseURL) endpoint := config.FileGet(name, "endpoint", storage.DefaultBaseURL)
client, err := storage.NewClient(account, key, endpoint, apiVersion, true) var (
if err != nil { oclient storage.Client
return nil, errors.Wrap(err, "failed to make azure storage client") client = &oclient
cc *storage.Container
)
switch {
case account != "" && key != "":
oclient, err = storage.NewClient(account, key, endpoint, apiVersion, true)
if err != nil {
return nil, errors.Wrap(err, "failed to make azure storage client from account/key")
}
case connectionString != "":
oclient, err = storage.NewClientFromConnectionString(connectionString)
if err != nil {
return nil, errors.Wrap(err, "failed to make azure storage client from connection string")
}
case sasURL != "":
URL, err := url.Parse(sasURL)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse SAS URL")
}
cc, err = storage.GetContainerReferenceFromSASURI(*URL)
if err != nil {
return nil, errors.Wrapf(err, "failed to make azure storage client from SAS URL")
}
client = cc.Client()
default:
return nil, errors.New("Need account+key or connectionString or sasURL")
} }
client.HTTPClient = fshttp.NewClient(fs.Config) client.HTTPClient = fshttp.NewClient(fs.Config)
bc := client.GetBlobService() bc := client.GetBlobService()
if cc == nil {
cc = bc.GetContainerReference(container)
}
f := &Fs{ f := &Fs{
name: name, name: name,
container: container, container: container,
root: directory, root: directory,
account: account, account: account,
key: keyBytes,
endpoint: endpoint, endpoint: endpoint,
bc: &bc, bc: &bc,
cc: bc.GetContainerReference(container), cc: cc,
pacer: pacer.New().SetMinSleep(minSleep).SetMaxSleep(maxSleep).SetDecayConstant(decayConstant), pacer: pacer.New().SetMinSleep(minSleep).SetMaxSleep(maxSleep).SetDecayConstant(decayConstant),
uploadToken: pacer.NewTokenDispenser(fs.Config.Transfers), uploadToken: pacer.NewTokenDispenser(fs.Config.Transfers),
} }