Skip to content

Commit 4abf868

Browse files
authored
Merge pull request #1568 from andyzhangx/fallback-sastoken-1.23
[release-1.23] fix: add fallback to sas token on azcopy copy command
2 parents d685531 + e9e5493 commit 4abf868

File tree

7 files changed

+29
-52
lines changed

7 files changed

+29
-52
lines changed

deploy/example/storageclass-blob-nfs.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ metadata:
66
provisioner: blob.csi.azure.com
77
parameters:
88
protocol: nfs
9-
useDataPlaneAPI: "false"
109
volumeBindingMode: Immediate
1110
allowVolumeExpansion: true
1211
mountOptions:

deploy/example/storageclass-blobfuse.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ metadata:
66
provisioner: blob.csi.azure.com
77
parameters:
88
skuName: Premium_LRS # available values: Standard_LRS, Premium_LRS, Standard_GRS, Standard_RAGRS
9-
useDataPlaneAPI: "false"
109
reclaimPolicy: Delete
1110
volumeBindingMode: Immediate
1211
allowVolumeExpansion: true

deploy/example/storageclass-blobfuse2.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ provisioner: blob.csi.azure.com
77
parameters:
88
skuName: Premium_LRS # available values: Standard_LRS, Premium_LRS, Standard_GRS, Standard_RAGRS
99
protocol: fuse2
10-
useDataPlaneAPI: "false"
1110
reclaimPolicy: Delete
1211
volumeBindingMode: Immediate
1312
allowVolumeExpansion: true

pkg/blob/controllerserver.go

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -430,12 +430,22 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
430430
return nil, status.Errorf(codes.Internal, "failed to create container(%s) on account(%s) type(%s) rg(%s) location(%s) size(%d), error: %v", validContainerName, accountName, storageAccountType, resourceGroup, location, requestGiB, err)
431431
}
432432
if volContentSource != nil {
433-
accountSASToken, authAzcopyEnv, err := d.getAzcopyAuth(ctx, accountName, accountKey, storageEndpointSuffix, accountOptions, secrets, secretName, secretNamespace)
433+
accountSASToken, authAzcopyEnv, err := d.getAzcopyAuth(ctx, accountName, accountKey, storageEndpointSuffix, accountOptions, secrets, secretName, secretNamespace, false)
434434
if err != nil {
435435
return nil, status.Errorf(codes.Internal, "failed to getAzcopyAuth on account(%s) rg(%s), error: %v", accountOptions.Name, accountOptions.ResourceGroup, err)
436436
}
437-
if err := d.copyVolume(ctx, req, accountName, accountSASToken, authAzcopyEnv, validContainerName, secretNamespace, accountOptions, storageEndpointSuffix); err != nil {
438-
return nil, err
437+
var copyErr error
438+
copyErr = d.copyVolume(ctx, req, accountName, accountSASToken, authAzcopyEnv, validContainerName, secretNamespace, accountOptions, storageEndpointSuffix)
439+
if accountSASToken == "" && copyErr != nil && strings.Contains(copyErr.Error(), authorizationPermissionMismatch) {
440+
klog.Warningf("azcopy copy failed with AuthorizationPermissionMismatch error, should assign \"Storage Blob Data Contributor\" role to controller identity, fall back to use sas token, original error: %v", copyErr)
441+
accountSASToken, authAzcopyEnv, err := d.getAzcopyAuth(ctx, accountName, accountKey, storageEndpointSuffix, accountOptions, secrets, secretName, secretNamespace, true)
442+
if err != nil {
443+
return nil, status.Errorf(codes.Internal, "failed to getAzcopyAuth on account(%s) rg(%s), error: %v", accountOptions.Name, accountOptions.ResourceGroup, err)
444+
}
445+
copyErr = d.copyVolume(ctx, req, accountName, accountSASToken, authAzcopyEnv, validContainerName, secretNamespace, accountOptions, storageEndpointSuffix)
446+
}
447+
if copyErr != nil {
448+
return nil, copyErr
439449
}
440450
}
441451

@@ -748,7 +758,7 @@ func (d *Driver) copyBlobContainer(ctx context.Context, req *csi.CreateVolumeReq
748758
SubscriptionID: srcSubscriptionID,
749759
GetLatestAccountKey: accountOptions.GetLatestAccountKey,
750760
}
751-
if srcAccountSasToken, _, err = d.getAzcopyAuth(ctx, srcAccountName, "", storageEndpointSuffix, srcAccountOptions, nil, "", secretNamespace); err != nil {
761+
if srcAccountSasToken, _, err = d.getAzcopyAuth(ctx, srcAccountName, "", storageEndpointSuffix, srcAccountOptions, nil, "", secretNamespace, true); err != nil {
752762
return err
753763
}
754764
}
@@ -841,12 +851,11 @@ func (d *Driver) authorizeAzcopyWithIdentity() ([]string, error) {
841851
// getAzcopyAuth will only generate sas token for azcopy in following conditions:
842852
// 1. secrets is not empty
843853
// 2. driver is not using managed identity and service principal
844-
// 3. azcopy returns AuthorizationPermissionMismatch error when using service principal or managed identity
845-
func (d *Driver) getAzcopyAuth(ctx context.Context, accountName, accountKey, storageEndpointSuffix string, accountOptions *azure.AccountOptions, secrets map[string]string, secretName, secretNamespace string) (string, []string, error) {
854+
// 3. parameter useSasToken is true
855+
func (d *Driver) getAzcopyAuth(ctx context.Context, accountName, accountKey, storageEndpointSuffix string, accountOptions *azure.AccountOptions, secrets map[string]string, secretName, secretNamespace string, useSasToken bool) (string, []string, error) {
846856
var authAzcopyEnv []string
847857
var err error
848-
useSasToken := false
849-
if !d.useDataPlaneAPI("", accountName) && len(secrets) == 0 && len(secretName) == 0 {
858+
if !useSasToken && !d.useDataPlaneAPI("", accountName) && len(secrets) == 0 && len(secretName) == 0 {
850859
// search in cache first
851860
if cache, err := d.azcopySasTokenCache.Get(accountName, azcache.CacheReadTypeDefault); err == nil && cache != nil {
852861
klog.V(2).Infof("use sas token for account(%s) since this account is found in azcopySasTokenCache", accountName)
@@ -856,17 +865,6 @@ func (d *Driver) getAzcopyAuth(ctx context.Context, accountName, accountKey, sto
856865
authAzcopyEnv, err = d.authorizeAzcopyWithIdentity()
857866
if err != nil {
858867
klog.Warningf("failed to authorize azcopy with identity, error: %v", err)
859-
} else {
860-
if len(authAzcopyEnv) > 0 {
861-
out, testErr := d.azcopy.TestListJobs(accountName, storageEndpointSuffix, authAzcopyEnv)
862-
if testErr != nil {
863-
return "", nil, fmt.Errorf("azcopy list command failed with error(%v): %v", testErr, out)
864-
}
865-
if strings.Contains(out, authorizationPermissionMismatch) {
866-
klog.Warningf("azcopy list failed with AuthorizationPermissionMismatch error, should assign \"Storage Blob Data Contributor\" role to controller identity, fall back to use sas token, original output: %v", out)
867-
useSasToken = true
868-
}
869-
}
870868
}
871869
}
872870

pkg/blob/controllerserver_test.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -817,12 +817,6 @@ func TestCreateVolume(t *testing.T) {
817817
ctrl := gomock.NewController(t)
818818
defer ctrl.Finish()
819819

820-
m := util.NewMockEXEC(ctrl)
821-
822-
listStr := "no error"
823-
m.EXPECT().RunCommand(gomock.Any(), gomock.Any()).Return(listStr, nil)
824-
d.azcopy.ExecCmd = m
825-
826820
expectedErr := status.Errorf(codes.NotFound, "error parsing volume id: \"unit-test\", should at least contain two #")
827821
_, err := d.CreateVolume(context.Background(), req)
828822
if !reflect.DeepEqual(err, expectedErr) {
@@ -1929,7 +1923,7 @@ func TestGetAzcopyAuth(t *testing.T) {
19291923
ctx := context.Background()
19301924
expectedAccountSASToken := ""
19311925
expectedErr := fmt.Errorf("could not find accountkey or azurestorageaccountkey field in secrets")
1932-
accountSASToken, _, err := d.getAzcopyAuth(ctx, "accountName", "", "core.windows.net", &azure.AccountOptions{}, secrets, "secretsName", "secretsNamespace")
1926+
accountSASToken, _, err := d.getAzcopyAuth(ctx, "accountName", "", "core.windows.net", &azure.AccountOptions{}, secrets, "secretsName", "secretsNamespace", false)
19331927
if !reflect.DeepEqual(err, expectedErr) || !reflect.DeepEqual(accountSASToken, expectedAccountSASToken) {
19341928
t.Errorf("Unexpected accountSASToken: %s, Unexpected error: %v", accountSASToken, err)
19351929
}
@@ -1952,7 +1946,7 @@ func TestGetAzcopyAuth(t *testing.T) {
19521946
defaultSecretAccountName: "accountName",
19531947
defaultSecretAccountKey: "YWNjb3VudGtleQo=",
19541948
}
1955-
accountSASToken, _, err := d.getAzcopyAuth(context.Background(), "accountName", "", "core.windows.net", &azure.AccountOptions{}, secrets, "secretsName", "secretsNamespace")
1949+
accountSASToken, _, err := d.getAzcopyAuth(context.Background(), "accountName", "", "core.windows.net", &azure.AccountOptions{}, secrets, "secretsName", "secretsNamespace", false)
19561950
if !reflect.DeepEqual(err, nil) || !strings.Contains(accountSASToken, "?se=") {
19571951
t.Errorf("Unexpected accountSASToken: %s, Unexpected error: %v", accountSASToken, err)
19581952
}
@@ -1978,7 +1972,7 @@ func TestGetAzcopyAuth(t *testing.T) {
19781972

19791973
expectedAccountSASToken := ""
19801974
expectedErr := status.Errorf(codes.Internal, fmt.Sprintf("failed to generate sas token in creating new shared key credential, accountName: %s, err: %s", "accountName", "decode account key: illegal base64 data at input byte 8"))
1981-
accountSASToken, _, err := d.getAzcopyAuth(context.Background(), "accountName", "", "core.windows.net", &azure.AccountOptions{}, secrets, "secretsName", "secretsNamespace")
1975+
accountSASToken, _, err := d.getAzcopyAuth(context.Background(), "accountName", "", "core.windows.net", &azure.AccountOptions{}, secrets, "secretsName", "secretsNamespace", false)
19821976
if !reflect.DeepEqual(err, expectedErr) || !reflect.DeepEqual(accountSASToken, expectedAccountSASToken) {
19831977
t.Errorf("Unexpected accountSASToken: %s, Unexpected error: %v", accountSASToken, err)
19841978
}
@@ -1999,7 +1993,7 @@ func TestGetAzcopyAuth(t *testing.T) {
19991993
ctx := context.Background()
20001994
expectedAccountSASToken := ""
20011995
expectedErr := status.Errorf(codes.Internal, fmt.Sprintf("failed to generate sas token in creating new shared key credential, accountName: %s, err: %s", "accountName", "decode account key: illegal base64 data at input byte 8"))
2002-
accountSASToken, _, err := d.getAzcopyAuth(ctx, "accountName", "", "core.windows.net", &azure.AccountOptions{}, secrets, "secretsName", "secretsNamespace")
1996+
accountSASToken, _, err := d.getAzcopyAuth(ctx, "accountName", "", "core.windows.net", &azure.AccountOptions{}, secrets, "secretsName", "secretsNamespace", false)
20031997
if !reflect.DeepEqual(err, expectedErr) || !reflect.DeepEqual(accountSASToken, expectedAccountSASToken) {
20041998
t.Errorf("Unexpected accountSASToken: %s, Unexpected error: %v", accountSASToken, err)
20051999
}

test/e2e/dynamic_provisioning_test.go

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,6 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Dynamic Provisioning", func() {
898898
Pod: pod,
899899
PodWithClonedVolume: podWithClonedVolume,
900900
StorageClassParameters: map[string]string{
901-
"useDataPlaneAPI": "true",
902901
"skuName": "Premium_LRS",
903902
"protocol": "nfs",
904903
"mountPermissions": "0755",
@@ -931,7 +930,6 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Dynamic Provisioning", func() {
931930
Pod: pod,
932931
PodWithClonedVolume: podWithClonedVolume,
933932
StorageClassParameters: map[string]string{
934-
"useDataPlaneAPI": "true",
935933
"skuName": "Premium_LRS",
936934
"protocol": "nfs",
937935
"mountPermissions": "0755",
@@ -965,9 +963,8 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Dynamic Provisioning", func() {
965963
Pod: pod,
966964
PodWithClonedVolume: podWithClonedVolume,
967965
StorageClassParameters: map[string]string{
968-
"useDataPlaneAPI": "true",
969-
"skuName": "Standard_LRS",
970-
"protocol": "fuse2",
966+
"skuName": "Standard_LRS",
967+
"protocol": "fuse2",
971968
},
972969
}
973970
test.Run(ctx, cs, ns)
@@ -998,9 +995,8 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Dynamic Provisioning", func() {
998995
Pod: pod,
999996
PodWithClonedVolume: podWithClonedVolume,
1000997
StorageClassParameters: map[string]string{
1001-
"useDataPlaneAPI": "true",
1002-
"skuName": "Standard_LRS",
1003-
"protocol": "fuse2",
998+
"skuName": "Standard_LRS",
999+
"protocol": "fuse2",
10041000
},
10051001
}
10061002
test.Run(ctx, cs, ns)
@@ -1030,14 +1026,12 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Dynamic Provisioning", func() {
10301026
Pod: pod,
10311027
PodWithClonedVolume: podWithClonedVolume,
10321028
StorageClassParameters: map[string]string{
1033-
"useDataPlaneAPI": "true",
10341029
"skuName": "Premium_LRS",
10351030
"protocol": "nfs",
10361031
"mountPermissions": "0755",
10371032
"allowsharedkeyaccess": "true",
10381033
},
10391034
ClonedStorageClassParameters: map[string]string{
1040-
"useDataPlaneAPI": "true",
10411035
"skuName": "Standard_LRS",
10421036
"protocol": "nfs",
10431037
"mountPermissions": "0755",
@@ -1072,14 +1066,12 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Dynamic Provisioning", func() {
10721066
Pod: pod,
10731067
PodWithClonedVolume: podWithClonedVolume,
10741068
StorageClassParameters: map[string]string{
1075-
"useDataPlaneAPI": "true",
1076-
"skuName": "Standard_LRS",
1077-
"protocol": "fuse2",
1069+
"skuName": "Standard_LRS",
1070+
"protocol": "fuse2",
10781071
},
10791072
ClonedStorageClassParameters: map[string]string{
1080-
"useDataPlaneAPI": "true",
1081-
"skuName": "Premium_LRS",
1082-
"protocol": "fuse2",
1073+
"skuName": "Premium_LRS",
1074+
"protocol": "fuse2",
10831075
},
10841076
}
10851077
test.Run(ctx, cs, ns)

test/external-e2e/run.sh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ setup_e2e_binaries() {
3434
sed -i "s/blob.csi.azure.com/$DRIVER.csi.azure.com/g" deploy/example/storageclass-blobfuse.yaml
3535
sed -i "s/blob.csi.azure.com/$DRIVER.csi.azure.com/g" deploy/example/storageclass-blobfuse2.yaml
3636
sed -i "s/blob.csi.azure.com/$DRIVER.csi.azure.com/g" deploy/example/storageclass-blob-nfs.yaml
37-
# workaround: use useDataPlaneAPI as true for blobfuse and nfs copy volume tests
38-
sed -i "s/\"false\"/\"true\"/g" deploy/example/storageclass-blobfuse.yaml
39-
sed -i "s/\"false\"/\"true\"/g" deploy/example/storageclass-blobfuse2.yaml
40-
sed -i "s/\"false\"/\"true\"/g" deploy/example/storageclass-blob-nfs.yaml
4137

4238
make e2e-bootstrap
4339
sed -i "s/csi-blob-controller/csi-$DRIVER-controller/g" deploy/example/metrics/csi-blob-controller-svc.yaml

0 commit comments

Comments
 (0)