From ce9f500a31419d56e4fa12dc54344a3f4daade35 Mon Sep 17 00:00:00 2001 From: Ahmet Alp Balkan Date: Mon, 23 Mar 2015 18:20:06 -0700 Subject: [PATCH] storage/driver/azure: Allow non-default realms This enables Azure storage driver to be used with non-default cloud endpoints like Azure China or Azure Government that does not use `.blob.core.windows.net` FQDN suffix. Signed-off-by: Ahmet Alp Balkan --- doc/storagedriver/azure.md | 1 + registry/storage/driver/azure/azure.go | 14 ++++++++++---- registry/storage/driver/azure/azure_test.go | 6 +++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/doc/storagedriver/azure.md b/doc/storagedriver/azure.md index f0fd296dd..3e27767ed 100644 --- a/doc/storagedriver/azure.md +++ b/doc/storagedriver/azure.md @@ -10,6 +10,7 @@ The following parameters must be used to authenticate and configure the storage * `accountname`: Name of the Azure Storage Account. * `accountkey`: Primary or Secondary Key for the Storage Account. * `container`: Name of the root storage container in which all registry data will be stored. Must comply the storage container name [requirements][create-container-api]. +* `realm`: (optional) Domain name suffix for the Storage Service API endpoint. Defaults to `core.windows.net`. For example realm for "Azure in China" would be `core.chinacloudapi.cn` and realm for "Azure Government" would be `core.usgovcloudapi.net`. [azure-blob-storage]: http://azure.microsoft.com/en-us/services/storage/ diff --git a/registry/storage/driver/azure/azure.go b/registry/storage/driver/azure/azure.go index 6ccbff40b..57d8acab5 100644 --- a/registry/storage/driver/azure/azure.go +++ b/registry/storage/driver/azure/azure.go @@ -24,6 +24,7 @@ const ( paramAccountName = "accountname" paramAccountKey = "accountkey" paramContainer = "container" + paramRealm = "realm" ) type driver struct { @@ -64,12 +65,17 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) { return nil, fmt.Errorf("No %s parameter provided", paramContainer) } - return New(fmt.Sprint(accountName), fmt.Sprint(accountKey), fmt.Sprint(container)) + realm, ok := parameters[paramRealm] + if !ok || fmt.Sprint(realm) == "" { + realm = azure.DefaultBaseUrl + } + + return New(fmt.Sprint(accountName), fmt.Sprint(accountKey), fmt.Sprint(container), fmt.Sprint(realm)) } // New constructs a new Driver with the given Azure Storage Account credentials -func New(accountName, accountKey, container string) (*Driver, error) { - api, err := azure.NewBasicClient(accountName, accountKey) +func New(accountName, accountKey, container, realm string) (*Driver, error) { + api, err := azure.NewClient(accountName, accountKey, realm, azure.DefaultApiVersion, true) if err != nil { return nil, err } @@ -343,5 +349,5 @@ func (d *driver) listBlobs(container, virtPath string) ([]string, error) { func is404(err error) bool { e, ok := err.(azure.StorageServiceError) - return ok && e.StatusCode == 404 + return ok && e.StatusCode == http.StatusNotFound } diff --git a/registry/storage/driver/azure/azure_test.go b/registry/storage/driver/azure/azure_test.go index a8fdf3e90..4990ba19b 100644 --- a/registry/storage/driver/azure/azure_test.go +++ b/registry/storage/driver/azure/azure_test.go @@ -15,6 +15,7 @@ const ( envAccountName = "AZURE_STORAGE_ACCOUNT_NAME" envAccountKey = "AZURE_STORAGE_ACCOUNT_KEY" envContainer = "AZURE_STORAGE_CONTAINER" + envRealm = "AZURE_STORAGE_REALM" ) // Hook up gocheck into the "go test" runner. @@ -25,6 +26,7 @@ func init() { accountName string accountKey string container string + realm string ) config := []struct { @@ -34,6 +36,7 @@ func init() { {envAccountName, &accountName}, {envAccountKey, &accountKey}, {envContainer, &container}, + {envRealm, &realm}, } missing := []string{} @@ -45,7 +48,7 @@ func init() { } azureDriverConstructor := func() (storagedriver.StorageDriver, error) { - return New(accountName, accountKey, container) + return New(accountName, accountKey, container, realm) } // Skip Azure storage driver tests if environment variable parameters are not provided @@ -61,5 +64,6 @@ func init() { // paramAccountName: accountName, // paramAccountKey: accountKey, // paramContainer: container, + // paramRealm: realm, // }, skipCheck) }