Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text eol=lf
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ can be augmented at runtime by implementing the `Getter` interface.
* Mercurial
* HTTP
* Amazon S3
* Azure Blob Storage
* Google GCP

In addition to the above protocols, go-getter has what are called "detectors."
Expand Down Expand Up @@ -360,3 +361,9 @@ In order to access to GCS, authentication credentials should be provided. More i
#### GCS Testing

The tests for `get_gcs.go` require you to have GCP credentials set in your environment. These credentials can have any level of permissions to any project, they just need to exist. This means setting `GOOGLE_APPLICATION_CREDENTIALS="~/path/to/credentials.json"` or `GOOGLE_CREDENTIALS="{stringified-credentials-json}"`. Due to this configuration, `get_gcs_test.go` will fail for external contributors in CircleCI.

### Azure Blob Storage (`azureblob`)

Azure Blob Storage requires a valid access key for the storage account, this can be provided by the
`ARM_ACCESS_KEY` environment variable, or the `access_key` query value which takes priority.

1 change: 1 addition & 0 deletions detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func init() {
new(GitDetector),
new(BitBucketDetector),
new(S3Detector),
new(AzureBlobDetector),
new(GCSDetector),
new(FileDetector),
}
Expand Down
51 changes: 51 additions & 0 deletions detect_azure_blob.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package getter

import (
"net/url"
"strings"

"fmt"

"github.com/Azure/go-autorest/autorest/azure"
)

var azureStorageSuffixes = map[string]azure.Environment{
azure.PublicCloud.StorageEndpointSuffix: azure.PublicCloud,
azure.GermanCloud.StorageEndpointSuffix: azure.GermanCloud,
azure.USGovernmentCloud.StorageEndpointSuffix: azure.USGovernmentCloud,
azure.ChinaCloud.StorageEndpointSuffix: azure.GermanCloud,
}

// AzureBlobDetector implements Detector to detect Azure URLs and turn
// them into URLs that the Azure getter can understand.
type AzureBlobDetector struct{}

func (d *AzureBlobDetector) Detect(src, _ string) (string, bool, error) {
if len(src) == 0 {
return "", false, nil
}

for s := range azureStorageSuffixes {
if strings.Contains(src, s) {
return d.detectURL(src)
}
}

return "", false, nil
}

func (d *AzureBlobDetector) detectURL(src string) (string, bool, error) {
u, err := url.Parse(src)
if err != nil {
return "", false, err
}

parts := strings.Split(u.Path, "/")
if len(parts) < 2 {
return "", false, fmt.Errorf("path to blob must not be empty")
}

u.Scheme = "https"

return fmt.Sprintf("azureblob::%s", u.String()), true, nil
}
50 changes: 50 additions & 0 deletions detect_azure_blob_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package getter

import (
"testing"
)

func TestAzureBlobDetector(t *testing.T) {
cases := []struct {
Input string
Output string
}{
{
"account.blob.core.windows.net/foo/bar",
"azureblob::https://account.blob.core.windows.net/foo/bar",
},
{
"account.blob.core.usgovcloudapi.net/foo/bar",
"azureblob::https://account.blob.core.usgovcloudapi.net/foo/bar",
},
{
"account.blob.core.chinacloudapi.cn/foo/bar",
"azureblob::https://account.blob.core.chinacloudapi.cn/foo/bar",
},
{
"account.blob.core.cloudapi.de/foo/bar",
"azureblob::https://account.blob.core.cloudapi.de/foo/bar",
},
// Misc tests
{
"account.blob.core.windows.net/foo/bar?version=1234",
"azureblob::https://account.blob.core.windows.net/foo/bar?version=1234",
},
}

pwd := "/pwd"
f := new(AzureBlobDetector)
for i, tc := range cases {
output, ok, err := f.Detect(tc.Input, pwd)
if err != nil {
t.Fatalf("err: %s", err)
}
if !ok {
t.Fatal("not ok")
}

if output != tc.Output {
t.Fatalf("%d: bad: %#v", i, output)
}
}
}
15 changes: 8 additions & 7 deletions get.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,14 @@ func init() {
}

Getters = map[string]Getter{
"file": new(FileGetter),
"git": new(GitGetter),
"gcs": new(GCSGetter),
"hg": new(HgGetter),
"s3": new(S3Getter),
"http": httpGetter,
"https": httpGetter,
"file": new(FileGetter),
"git": new(GitGetter),
"gcs": new(GCSGetter),
"hg": new(HgGetter),
"s3": new(S3Getter),
"azureblob": new(AzureBlobGetter),
"http": httpGetter,
"https": httpGetter,
}
}

Expand Down
Loading