sigs.k8s.io/blob-csi-driver@v1.24.1/test/e2e/testsuites/pre_provisioned_provided_credentials_tester.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package testsuites 18 19 import ( 20 "context" 21 "fmt" 22 "strings" 23 24 "github.com/onsi/ginkgo/v2" 25 26 "sigs.k8s.io/blob-csi-driver/pkg/blob" 27 "sigs.k8s.io/blob-csi-driver/test/e2e/driver" 28 "sigs.k8s.io/blob-csi-driver/test/utils/azure" 29 30 v1 "k8s.io/api/core/v1" 31 clientset "k8s.io/client-go/kubernetes" 32 "k8s.io/kubernetes/test/e2e/framework" 33 ) 34 35 // PreProvisionedProvidedCredentiasTest will provision required PV(s), PVC(s) and Pod(s) 36 // Testing that the Pod(s) can be created successfully with provided storage account name and key(or sastoken) 37 type PreProvisionedProvidedCredentiasTest struct { 38 CSIDriver driver.PreProvisionedVolumeTestDriver 39 Pods []PodDetails 40 Driver *blob.Driver 41 } 42 43 func (t *PreProvisionedProvidedCredentiasTest) Run(ctx context.Context, client clientset.Interface, namespace *v1.Namespace) { 44 kvClient, err := azure.NewKeyVaultClient() 45 framework.ExpectNoError(err) 46 47 authClient, err := azure.NewAuthorizationClient() 48 framework.ExpectNoError(err) 49 50 for _, pod := range t.Pods { 51 for n, volume := range pod.Volumes { 52 accountName, accountKey, _, _, err := t.Driver.GetStorageAccountAndContainer(ctx, volume.VolumeID, nil, nil) 53 framework.ExpectNoError(err, fmt.Sprintf("Error GetStorageAccountAndContainer from volumeID(%s): %v", volume.VolumeID, err)) 54 var secretData map[string]string 55 var i int 56 var run = func() { 57 // add suffix to volumeID to force kubelet to NodeStageVolume every time, 58 // otherwise it will skip NodeStageVolume for the same VolumeID(VolumeHanlde) 59 pod.Volumes[n].VolumeID = fmt.Sprintf("%s-%d", volume.VolumeID, i) 60 i++ 61 62 tsecret := NewTestSecret(client, namespace, volume.NodeStageSecretRef, secretData) 63 tsecret.Create(ctx) 64 defer tsecret.Cleanup(ctx) 65 66 tpod, cleanup := pod.SetupWithPreProvisionedVolumes(ctx, client, namespace, t.CSIDriver) 67 // defer must be called here for resources not get removed before using them 68 for i := range cleanup { 69 defer cleanup[i](ctx) 70 } 71 72 ginkgo.By("deploying the pod") 73 tpod.Create(ctx) 74 defer func() { 75 tpod.Cleanup(ctx) 76 }() 77 78 ginkgo.By("checking that the pods command exits with no error") 79 tpod.WaitForSuccess(ctx) 80 } 81 82 // test for storage account key 83 ginkgo.By("Run for storage account key") 84 secretData = map[string]string{ 85 "azurestorageaccountname": accountName, 86 "azurestorageaccountkey": accountKey, 87 } 88 run() 89 90 // test for storage account SAS token 91 ginkgo.By("Run for storage account SAS token") 92 pod.Volumes[n].Attrib = map[string]string{ 93 "azurestorageauthtype": "SAS", 94 } 95 sasToken := GenerateSASToken(accountName, accountKey) 96 secretData = map[string]string{ 97 "azurestorageaccountname": accountName, 98 "azurestorageaccountsastoken": sasToken, 99 } 100 run() 101 102 // test for service principal 103 ginkgo.By("Run for service principal") 104 pod.Volumes[n].Attrib = map[string]string{ 105 "azurestorageauthtype": "SPN", 106 "azurestoragespnclientid": kvClient.Cred.AADClientID, 107 "azurestoragespntenantid": kvClient.Cred.TenantID, 108 } 109 secretData = map[string]string{ 110 "azurestorageaccountname": accountName, 111 "azurestoragespnclientsecret": kvClient.Cred.AADClientSecret, 112 } 113 114 // assign role to service principal 115 objectID, err := kvClient.GetServicePrincipalObjectID(ctx, kvClient.Cred.AADClientID) 116 framework.ExpectNoError(err, fmt.Sprintf("Error GetServicePrincipalObjectID from clientID(%s): %v", kvClient.Cred.AADClientID, err)) 117 118 resourceID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s", kvClient.Cred.SubscriptionID, kvClient.Cred.ResourceGroup, accountName) 119 120 ginkgo.By(fmt.Sprintf("assign Storage Blob Data Contributor role to the service principal, objectID:%s", objectID)) 121 roleDef, err := authClient.GetRoleDefinition(ctx, resourceID, "Storage Blob Data Contributor") 122 framework.ExpectNoError(err, fmt.Sprintf("Error GetRoleDefinition from resourceID(%s): %v", resourceID, err)) 123 124 roleDefID := *roleDef.ID 125 _, err = authClient.AssignRole(ctx, resourceID, objectID, roleDefID) 126 if err != nil && strings.Contains(err.Error(), "The role assignment already exists") { 127 err = nil 128 } 129 framework.ExpectNoError(err, fmt.Sprintf("Error AssignRole (roleDefID(%s)) to objectID(%s) to access resource (resourceID(%s)), error: %v", roleDefID, objectID, resourceID, err)) 130 131 run() 132 133 // test for managed identity(objectID) 134 objectID, err = kvClient.GetMSIObjectID(ctx, "blobfuse-csi-driver-e2e-test-id") 135 if err != nil { 136 // only e2e-vmss test job will use msi blobfuse-csi-driver-e2e-test-id, other jobs use service principal, so skip here 137 return 138 } 139 140 ginkgo.By(fmt.Sprintf("Run for managed identity (objectID %s)", objectID)) 141 pod.Volumes[n].Attrib = map[string]string{ 142 "azurestorageauthtype": "MSI", 143 "azurestorageidentityobjectid": objectID, 144 } 145 146 secretData = map[string]string{ 147 "azurestorageaccountname": accountName, 148 } 149 ginkgo.By(fmt.Sprintf("assign Storage Blob Data Contributor role to the managed identity, objectID:%s", objectID)) 150 _, err = authClient.AssignRole(ctx, resourceID, objectID, roleDefID) 151 if err != nil && strings.Contains(err.Error(), "The role assignment already exists") { 152 err = nil 153 } 154 framework.ExpectNoError(err, fmt.Sprintf("Error AssignRole (roleDefID(%s)) to objectID(%s) to access resource (resourceID(%s)), error: %v", roleDefID, objectID, resourceID, err)) 155 156 run() 157 158 // test for managed identity(resourceID) 159 resourceID, err = kvClient.GetMSIResourceID(ctx, "blobfuse-csi-driver-e2e-test-id") 160 if err != nil { 161 // only e2e-vmss test job will use msi blobfuse-csi-driver-e2e-test-id, other jobs use service principal, so skip here 162 return 163 } 164 ginkgo.By(fmt.Sprintf("Run for managed identity (resourceID %s)", resourceID)) 165 pod.Volumes[n].Attrib = map[string]string{ 166 "azurestorageauthtype": "MSI", 167 "azurestorageidentityresourceid": resourceID, 168 } 169 secretData = map[string]string{ 170 "azurestorageaccountname": accountName, 171 } 172 173 run() 174 } 175 } 176 }