diff --git a/pkg/block/azure/adapter.go b/pkg/block/azure/adapter.go index 0fd72ae8c1d..ad609633d57 100644 --- a/pkg/block/azure/adapter.go +++ b/pkg/block/azure/adapter.go @@ -29,7 +29,8 @@ const ( // more the 5000 different accounts, which is highly unlikely udcCacheSize = 5000 - BlobEndpointFormat = "https://%s.blob.core.windows.net/" + BlobEndpointGeneralFormat = "https://%s.blob.core.windows.net/" + BlobEndpointChinaCloudFormat = "https://%s.blob.core.chinacloudapi.cn/" ) type Adapter struct { @@ -37,6 +38,7 @@ type Adapter struct { preSignedExpiry time.Duration disablePreSigned bool disablePreSignedUI bool + chinaCloud bool } func NewAdapter(ctx context.Context, params params.Azure) (*Adapter, error) { @@ -54,6 +56,7 @@ func NewAdapter(ctx context.Context, params params.Azure) (*Adapter, error) { preSignedExpiry: preSignedExpiry, disablePreSigned: params.DisablePreSigned, disablePreSignedUI: params.DisablePreSignedUI, + chinaCloud: params.ChinaCloud, }, nil } @@ -62,6 +65,7 @@ type BlobURLInfo struct { ContainerURL string ContainerName string BlobURL string + Host string } type PrefixURLInfo struct { @@ -106,6 +110,7 @@ func ResolveBlobURLInfoFromURL(pathURL *url.URL) (BlobURLInfo, error) { ContainerURL: fmt.Sprintf("%s://%s/%s", pathURL.Scheme, pathURL.Host, pathParts[0]), ContainerName: pathParts[0], BlobURL: strings.Join(pathParts[1:], "/"), + Host: pathURL.Host, }, nil } @@ -131,6 +136,7 @@ func resolveBlobURLInfo(obj block.ObjectPointer) (BlobURLInfo, error) { ContainerURL: qp.ContainerURL, ContainerName: qp.ContainerName, BlobURL: qp.BlobURL + "/" + key, + Host: parsedNamespace.Host, } if qp.BlobURL == "" { info.BlobURL = key @@ -266,7 +272,7 @@ func (a *Adapter) getPreSignedURL(ctx context.Context, obj block.ObjectPointer, } // format blob URL with signed SAS query params - accountEndpoint := fmt.Sprintf(BlobEndpointFormat, qualifiedKey.StorageAccountName) + accountEndpoint := buildAccountEndpoint(qualifiedKey.StorageAccountName, a.chinaCloud) u, err := url.JoinPath(accountEndpoint, qualifiedKey.ContainerName, qualifiedKey.BlobURL) if err != nil { return "", err diff --git a/pkg/block/azure/client_cache.go b/pkg/block/azure/client_cache.go index 2d54908812a..6e35b658807 100644 --- a/pkg/block/azure/client_cache.go +++ b/pkg/block/azure/client_cache.go @@ -124,7 +124,7 @@ func BuildAzureServiceClient(params params.Azure) (*service.Client, error) { if params.TestEndpointURL != "" { // For testing purposes - override default url template url = params.TestEndpointURL } else { - url = fmt.Sprintf(BlobEndpointFormat, params.StorageAccount) + url = buildAccountEndpoint(params.StorageAccount, params.ChinaCloud) } options := service.ClientOptions{ClientOptions: azcore.ClientOptions{Retry: policy.RetryOptions{TryTimeout: params.TryTimeout}}} @@ -142,3 +142,11 @@ func BuildAzureServiceClient(params params.Azure) (*service.Client, error) { } return service.NewClient(url, defaultCreds, &options) } + +func buildAccountEndpoint(storageAccount string, chinaCloud bool) string { + format := BlobEndpointGeneralFormat + if chinaCloud { + format = BlobEndpointChinaCloudFormat + } + return fmt.Sprintf(format, storageAccount) +} diff --git a/pkg/block/params/block.go b/pkg/block/params/block.go index ffab817c3f0..47e10a9d047 100644 --- a/pkg/block/params/block.go +++ b/pkg/block/params/block.go @@ -77,6 +77,8 @@ type Azure struct { PreSignedExpiry time.Duration DisablePreSigned bool DisablePreSignedUI bool + // Azure China Cloud has different endpoints, different services and it's isolated from Azure Global Cloud + ChinaCloud bool // TestEndpointURL - For testing purposes, provide a custom URL to override the default URL template TestEndpointURL string } diff --git a/pkg/config/config.go b/pkg/config/config.go index 23a19697377..4747c530ed6 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -248,6 +248,7 @@ type Config struct { PreSignedExpiry time.Duration `mapstructure:"pre_signed_expiry"` DisablePreSigned bool `mapstructure:"disable_pre_signed"` DisablePreSignedUI bool `mapstructure:"disable_pre_signed_ui"` + ChinaCloud bool `mapstructure:"china_cloud"` // TestEndpointURL for testing purposes TestEndpointURL string `mapstructure:"test_endpoint_url"` } `mapstructure:"azure"` @@ -503,6 +504,7 @@ func (c *Config) BlockstoreAzureParams() (blockparams.Azure, error) { TestEndpointURL: c.Blockstore.Azure.TestEndpointURL, DisablePreSigned: c.Blockstore.Azure.DisablePreSigned, DisablePreSignedUI: c.Blockstore.Azure.DisablePreSignedUI, + ChinaCloud: c.Blockstore.Azure.ChinaCloud, }, nil }