From ff6868900d5a2adcbf9ead9acf9e4285edc245c5 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Mon, 15 Mar 2021 22:48:47 +0530 Subject: [PATCH] azureblob: add container public access level support. Fixes #5045 --- backend/azureblob/azureblob.go | 40 +++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/backend/azureblob/azureblob.go b/backend/azureblob/azureblob.go index 3701de1a0..fea7a0459 100644 --- a/backend/azureblob/azureblob.go +++ b/backend/azureblob/azureblob.go @@ -217,6 +217,23 @@ This option controls how often unused buffers will be removed from the pool.`, encoder.EncodeDel | encoder.EncodeBackSlash | encoder.EncodeRightPeriod), + }, { + Name: "public_access", + Help: "Public access level of a container: blob, container.", + Default: string(azblob.PublicAccessNone), + Examples: []fs.OptionExample{ + { + Value: string(azblob.PublicAccessNone), + Help: "The container and its blobs can be accessed only with an authorized request. It's a default value", + }, { + Value: string(azblob.PublicAccessBlob), + Help: "Blob data within this container can be read via anonymous request.", + }, { + Value: string(azblob.PublicAccessContainer), + Help: "Allow full public read access for container and blob data.", + }, + }, + Advanced: true, }}, }) } @@ -241,6 +258,7 @@ type Options struct { MemoryPoolFlushTime fs.Duration `config:"memory_pool_flush_time"` MemoryPoolUseMmap bool `config:"memory_pool_use_mmap"` Enc encoder.MultiEncoder `config:"encoding"` + PublicAccess string `config:"public_access"` } // Fs represents a remote azure server @@ -262,6 +280,7 @@ type Fs struct { imdsPacer *fs.Pacer // Same but for IMDS uploadToken *pacer.TokenDispenser // control concurrency pool *pool.Pool // memory pool + publicAccess azblob.PublicAccessType // Container Public Access Level } // Object describes an azure object @@ -335,6 +354,19 @@ func validateAccessTier(tier string) bool { } } +// validatePublicAccess checks if azureblob supports use supplied public access level +func validatePublicAccess(publicAccess string) bool { + switch publicAccess { + case string(azblob.PublicAccessNone), + string(azblob.PublicAccessBlob), + string(azblob.PublicAccessContainer): + // valid cases + return true + default: + return false + } +} + // retryErrorCodes is a slice of error codes that we will retry var retryErrorCodes = []int{ 401, // Unauthorized (e.g. "Token has expired") @@ -502,6 +534,11 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e string(azblob.AccessTierHot), string(azblob.AccessTierCool), string(azblob.AccessTierArchive)) } + if !validatePublicAccess((opt.PublicAccess)) { + return nil, errors.Errorf("Azure Blob: Supported public access level are %s and %s", + string(azblob.PublicAccessBlob), string(azblob.PublicAccessContainer)) + } + ci := fs.GetConfig(ctx) f := &Fs{ name: name, @@ -520,6 +557,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e opt.MemoryPoolUseMmap, ), } + f.publicAccess = azblob.PublicAccessType(opt.PublicAccess) f.imdsPacer.SetRetries(5) // per IMDS documentation f.setRoot(root) f.features = (&fs.Features{ @@ -1084,7 +1122,7 @@ func (f *Fs) makeContainer(ctx context.Context, container string) error { } // now try to create the container return f.pacer.Call(func() (bool, error) { - _, err := f.cntURL(container).Create(ctx, azblob.Metadata{}, azblob.PublicAccessNone) + _, err := f.cntURL(container).Create(ctx, azblob.Metadata{}, f.publicAccess) if err != nil { if storageErr, ok := err.(azblob.StorageError); ok { switch storageErr.ServiceCode() {