@@ -19,61 +19,28 @@ package testsuites
19
19
import (
20
20
"context"
21
21
"fmt"
22
- "net/url"
23
- "time"
24
22
25
- "github.com/Azure/azure-sdk-for-go/sdk/azcore"
26
- "github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
27
- "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
28
- "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault"
29
- "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
30
- "github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac"
31
- "github.com/Azure/azure-sdk-for-go/services/msi/mgmt/2018-11-30/msi"
32
- "github.com/Azure/go-autorest/autorest"
33
- "github.com/Azure/go-autorest/autorest/adal"
34
- "github.com/Azure/go-autorest/autorest/azure"
35
23
"github.com/onsi/ginkgo"
36
24
v1 "k8s.io/api/core/v1"
37
- "k8s.io/apiserver/pkg/storage/names"
38
25
clientset "k8s.io/client-go/kubernetes"
39
26
"k8s.io/kubernetes/test/e2e/framework"
40
27
"sigs.k8s.io/blob-csi-driver/pkg/blob"
41
28
"sigs.k8s.io/blob-csi-driver/test/e2e/driver"
42
- "sigs.k8s.io/blob-csi-driver/test/utils/credentials"
43
- )
44
-
45
- var (
46
- subscriptionID string
47
- resourceGroupName string
48
- location string
49
- vaultName string
50
- TenantID string
51
- cloud string
52
- clientID string
53
- clientSecret string
29
+ "sigs.k8s.io/blob-csi-driver/test/utils/azure"
54
30
)
55
31
56
32
// PreProvisionedKeyVaultTest will provision required PV(s), PVC(s) and Pod(s)
57
33
// Testing that the Pod(s) can be created successfully with provided Key Vault
58
- // which is used to store storage account name and key(or sastoken)
34
+ // which is used to store storage account name and key
59
35
type PreProvisionedKeyVaultTest struct {
60
36
CSIDriver driver.PreProvisionedVolumeTestDriver
61
37
Pods []PodDetails
62
38
Driver * blob.Driver
63
39
}
64
40
65
41
func (t * PreProvisionedKeyVaultTest ) Run (client clientset.Interface , namespace * v1.Namespace ) {
66
- e2eCred , err := credentials .ParseAzureCredentialFile ()
67
- framework .ExpectNoError (err , fmt .Sprintf ("Error ParseAzureCredentialFile: %v" , err ))
68
-
69
- subscriptionID = e2eCred .SubscriptionID
70
- resourceGroupName = e2eCred .ResourceGroup
71
- location = e2eCred .Location
72
- TenantID = e2eCred .TenantID
73
- cloud = e2eCred .Cloud
74
- clientID = e2eCred .AADClientID
75
- clientSecret = e2eCred .AADClientSecret
76
- vaultName = names .SimpleNameGenerator .GenerateName ("blob-csi-test-kv-" )
42
+ keyVaultClient , err := azure .NewKeyVaultClient ()
43
+ framework .ExpectNoError (err )
77
44
78
45
for _ , pod := range t .Pods {
79
46
for n , volume := range pod .Volumes {
@@ -82,291 +49,36 @@ func (t *PreProvisionedKeyVaultTest) Run(client clientset.Interface, namespace *
82
49
accountName , accountKey , _ , containerName , err := t .Driver .GetStorageAccountAndContainer (context .TODO (), volume .VolumeID , nil , nil )
83
50
framework .ExpectNoError (err , fmt .Sprintf ("Error GetStorageAccountAndContainer from volumeID(%s): %v" , volume .VolumeID , err ))
84
51
85
- azureCred , err := azidentity .NewDefaultAzureCredential (nil )
86
- framework .ExpectNoError (err )
87
-
88
52
ginkgo .By ("creating KeyVault..." )
89
- vault , err := createVault (context .TODO (), azureCred )
53
+ vault , err := keyVaultClient . CreateVault (context .TODO ())
90
54
framework .ExpectNoError (err )
91
- defer cleanVault (context .TODO (), azureCred )
55
+ defer func () {
56
+ err := keyVaultClient .CleanVault (context .TODO ())
57
+ framework .ExpectNoError (err )
58
+ }()
92
59
93
60
ginkgo .By ("creating secret for storage account key..." )
94
- accountKeySecret , err := createSecret (context .TODO (), azureCred , accountName + "-key" , accountKey )
61
+ accountKeySecret , err := keyVaultClient . CreateSecret (context .TODO (), accountName + "-key" , accountKey )
95
62
framework .ExpectNoError (err )
96
63
97
64
pod .Volumes [n ].ContainerName = containerName
98
65
pod .Volumes [n ].StorageAccountname = accountName
99
66
pod .Volumes [n ].KeyVaultURL = * vault .Properties .VaultURI
100
67
pod .Volumes [n ].KeyVaultSecretName = * accountKeySecret .Name
101
- // test for Account key
102
- ginkgo .By ("test storage account key..." )
103
- run (pod , client , namespace , t .CSIDriver )
104
-
105
- ginkgo .By ("generate SAS token..." )
106
- sasToken := generateSASToken (accountName , accountKey )
107
-
108
- ginkgo .By ("creating secret for SAS token..." )
109
- accountSASSecret , err := createSecret (context .TODO (), azureCred , accountName + "-sas" , sasToken )
110
- framework .ExpectNoError (err )
111
68
112
- pod .Volumes [n ].KeyVaultSecretName = * accountSASSecret .Name
113
- // TODO: test for SAS token
114
- // ginkgo.By("test SAS token...")
115
- // run(pod, client, namespace, t.CSIDriver)
69
+ ginkgo .By ("test storage account key..." )
70
+ tpod , cleanup := pod .SetupWithPreProvisionedVolumes (client , namespace , t .CSIDriver )
71
+ // defer must be called here for resources not get removed before using them
72
+ for i := range cleanup {
73
+ defer cleanup [i ]()
74
+ }
75
+
76
+ ginkgo .By ("deploying the pod" )
77
+ tpod .Create ()
78
+ defer tpod .Cleanup ()
79
+
80
+ ginkgo .By ("checking that the pods command exits with no error" )
81
+ tpod .WaitForSuccess ()
116
82
}
117
83
}
118
84
}
119
-
120
- func run (pod PodDetails , client clientset.Interface , namespace * v1.Namespace , csidriver driver.PreProvisionedVolumeTestDriver ) {
121
- tpod , cleanup := pod .SetupWithPreProvisionedVolumes (client , namespace , csidriver )
122
- // defer must be called here for resources not get removed before using them
123
- for i := range cleanup {
124
- defer cleanup [i ]()
125
- }
126
-
127
- ginkgo .By ("deploying the pod" )
128
- tpod .Create ()
129
- defer tpod .Cleanup ()
130
-
131
- ginkgo .By ("checking that the pods command exits with no error" )
132
- tpod .WaitForSuccess ()
133
- }
134
-
135
- func generateSASToken (accountName , accountKey string ) string {
136
- credential , err := azblob .NewSharedKeyCredential (accountName , accountKey )
137
- framework .ExpectNoError (err )
138
- serviceClient , err := azblob .NewServiceClientWithSharedKey (fmt .Sprintf ("https://%s.blob.core.windows.net/" , accountName ), credential , nil )
139
- framework .ExpectNoError (err )
140
- sasURL , err := serviceClient .GetSASURL (
141
- azblob.AccountSASResourceTypes {Object : true , Service : true , Container : true },
142
- azblob.AccountSASPermissions {Read : true , List : true , Write : true , Delete : true , Add : true , Create : true , Update : true },
143
- time .Now (), time .Now ().Add (12 * time .Hour ))
144
- framework .ExpectNoError (err )
145
- ginkgo .By ("sas URL: " + sasURL )
146
- u , err := url .Parse (sasURL )
147
- framework .ExpectNoError (err )
148
- queryUnescape , err := url .QueryUnescape (u .RawQuery )
149
- framework .ExpectNoError (err )
150
- sasToken := "?" + queryUnescape
151
- ginkgo .By ("sas Token: " + sasToken )
152
- return sasToken
153
- }
154
-
155
- func createVault (ctx context.Context , cred azcore.TokenCredential ) (* armkeyvault.Vault , error ) {
156
- vaultsClient , err := armkeyvault .NewVaultsClient (subscriptionID , cred , nil )
157
- if err != nil {
158
- return nil , err
159
- }
160
-
161
- pollerResp , err := vaultsClient .BeginCreateOrUpdate (
162
- ctx ,
163
- resourceGroupName ,
164
- vaultName ,
165
- armkeyvault.VaultCreateOrUpdateParameters {
166
- Location : to .Ptr (location ),
167
- Properties : & armkeyvault.VaultProperties {
168
- SKU : & armkeyvault.SKU {
169
- Family : to .Ptr (armkeyvault .SKUFamilyA ),
170
- Name : to .Ptr (armkeyvault .SKUNameStandard ),
171
- },
172
- TenantID : to .Ptr (TenantID ),
173
- AccessPolicies : getAccessPolicy (ctx ),
174
- },
175
- },
176
- nil ,
177
- )
178
- if err != nil {
179
- return nil , err
180
- }
181
-
182
- resp , err := pollerResp .PollUntilDone (ctx , nil )
183
- if err != nil {
184
- return nil , err
185
- }
186
- return & resp .Vault , nil
187
- }
188
-
189
- func getAccessPolicy (ctx context.Context ) []* armkeyvault.AccessPolicyEntry {
190
- accessPolicyEntry := []* armkeyvault.AccessPolicyEntry {}
191
-
192
- // vault secret permission for upstream e2e test, which uses application service principal
193
- clientObjectID , err := getServicePrincipalObjectID (ctx , clientID )
194
- if err == nil {
195
- ginkgo .By ("client object ID: " + clientObjectID )
196
- accessPolicyEntry = append (accessPolicyEntry , & armkeyvault.AccessPolicyEntry {
197
- TenantID : to .Ptr (TenantID ),
198
- ObjectID : to .Ptr (clientObjectID ),
199
- Permissions : & armkeyvault.Permissions {
200
- Secrets : []* armkeyvault.SecretPermissions {
201
- to .Ptr (armkeyvault .SecretPermissionsGet ),
202
- },
203
- },
204
- })
205
- }
206
-
207
- // vault secret permission for upstream e2e-vmss test, which uses msi blobfuse-csi-driver-e2e-test-id
208
- msiObjectID , err := getMSIObjectID (ctx , "blobfuse-csi-driver-e2e-test-id" )
209
- if err == nil {
210
- ginkgo .By ("MSI object ID: " + msiObjectID )
211
- accessPolicyEntry = append (accessPolicyEntry , & armkeyvault.AccessPolicyEntry {
212
- TenantID : to .Ptr (TenantID ),
213
- ObjectID : to .Ptr (msiObjectID ),
214
- Permissions : & armkeyvault.Permissions {
215
- Secrets : []* armkeyvault.SecretPermissions {
216
- to .Ptr (armkeyvault .SecretPermissionsGet ),
217
- },
218
- },
219
- })
220
- }
221
-
222
- return accessPolicyEntry
223
- }
224
-
225
- func cleanVault (ctx context.Context , cred azcore.TokenCredential ) {
226
- err := deleteVault (ctx , cred )
227
- framework .ExpectNoError (err )
228
-
229
- err = purgeDeleted (ctx , cred )
230
- framework .ExpectNoError (err )
231
- }
232
-
233
- func deleteVault (ctx context.Context , cred azcore.TokenCredential ) error {
234
- vaultsClient , err := armkeyvault .NewVaultsClient (subscriptionID , cred , nil )
235
- if err != nil {
236
- return err
237
- }
238
-
239
- _ , err = vaultsClient .Delete (ctx , resourceGroupName , vaultName , nil )
240
- if err != nil {
241
- return err
242
- }
243
- return nil
244
- }
245
-
246
- func purgeDeleted (ctx context.Context , cred azcore.TokenCredential ) error {
247
- vaultsClient , err := armkeyvault .NewVaultsClient (subscriptionID , cred , nil )
248
- if err != nil {
249
- return err
250
- }
251
-
252
- pollerResp , err := vaultsClient .BeginPurgeDeleted (ctx , vaultName , location , nil )
253
- if err != nil {
254
- return err
255
- }
256
-
257
- _ , err = pollerResp .PollUntilDone (ctx , nil )
258
- if err != nil {
259
- return err
260
- }
261
-
262
- return nil
263
- }
264
-
265
- func createSecret (ctx context.Context , cred azcore.TokenCredential , secretName , secretValue string ) (* armkeyvault.Secret , error ) {
266
- secretsClient , err := armkeyvault .NewSecretsClient (subscriptionID , cred , nil )
267
- if err != nil {
268
- return nil , err
269
- }
270
-
271
- secretResp , err := secretsClient .CreateOrUpdate (
272
- ctx ,
273
- resourceGroupName ,
274
- vaultName ,
275
- secretName ,
276
- armkeyvault.SecretCreateOrUpdateParameters {
277
- Properties : & armkeyvault.SecretProperties {
278
- Attributes : & armkeyvault.SecretAttributes {
279
- Enabled : to .Ptr (true ),
280
- },
281
- Value : to .Ptr (secretValue ),
282
- },
283
- },
284
- nil ,
285
- )
286
- if err != nil {
287
- return nil , err
288
- }
289
-
290
- return & secretResp .Secret , nil
291
- }
292
-
293
- func getServicePrincipalObjectID (ctx context.Context , clientID string ) (string , error ) {
294
- spClient , err := getServicePrincipalsClient ()
295
- if err != nil {
296
- return "" , err
297
- }
298
-
299
- page , err := spClient .List (ctx , fmt .Sprintf ("servicePrincipalNames/any(c:c eq '%s')" , clientID ))
300
- if err != nil {
301
- return "" , err
302
- }
303
- servicePrincipals := page .Values ()
304
- if len (servicePrincipals ) == 0 {
305
- return "" , fmt .Errorf ("didn't find any service principals for client ID %s" , clientID )
306
- }
307
- return * servicePrincipals [0 ].ObjectID , nil
308
- }
309
-
310
- func getServicePrincipalsClient () (* graphrbac.ServicePrincipalsClient , error ) {
311
- spClient := graphrbac .NewServicePrincipalsClient (TenantID )
312
-
313
- env , err := azure .EnvironmentFromName (cloud )
314
- if err != nil {
315
- return nil , err
316
- }
317
-
318
- oauthConfig , err := adal .NewOAuthConfig (env .ActiveDirectoryEndpoint , TenantID )
319
- if err != nil {
320
- return nil , err
321
- }
322
-
323
- token , err := adal .NewServicePrincipalToken (* oauthConfig , clientID , clientSecret , env .GraphEndpoint )
324
- if err != nil {
325
- return nil , err
326
- }
327
-
328
- authorizer := autorest .NewBearerAuthorizer (token )
329
-
330
- spClient .Authorizer = authorizer
331
-
332
- return & spClient , nil
333
- }
334
-
335
- func getMSIUserAssignedIDClient () (* msi.UserAssignedIdentitiesClient , error ) {
336
- msiClient := msi .NewUserAssignedIdentitiesClient (subscriptionID )
337
-
338
- env , err := azure .EnvironmentFromName (cloud )
339
- if err != nil {
340
- return nil , err
341
- }
342
-
343
- oauthConfig , err := adal .NewOAuthConfig (env .ActiveDirectoryEndpoint , TenantID )
344
- if err != nil {
345
- return nil , err
346
- }
347
-
348
- token , err := adal .NewServicePrincipalToken (* oauthConfig , clientID , clientSecret , env .ResourceManagerEndpoint )
349
- if err != nil {
350
- return nil , err
351
- }
352
-
353
- authorizer := autorest .NewBearerAuthorizer (token )
354
-
355
- msiClient .Authorizer = authorizer
356
-
357
- return & msiClient , nil
358
- }
359
-
360
- func getMSIObjectID (ctx context.Context , identityName string ) (string , error ) {
361
- msiClient , err := getMSIUserAssignedIDClient ()
362
- if err != nil {
363
- return "" , err
364
- }
365
-
366
- id , err := msiClient .Get (ctx , resourceGroupName , identityName )
367
- if err != nil {
368
- return "" , err
369
- }
370
-
371
- return id .UserAssignedIdentityProperties .PrincipalID .String (), err
372
- }
0 commit comments