@@ -15,6 +15,8 @@ limitations under the License.
15
15
package tests
16
16
17
17
import (
18
+ "context"
19
+ "fmt"
18
20
"strings"
19
21
"time"
20
22
@@ -26,6 +28,10 @@ import (
26
28
csi "github.com/container-storage-interface/spec/lib/go/csi"
27
29
. "github.com/onsi/ginkgo"
28
30
. "github.com/onsi/gomega"
31
+
32
+ "google.golang.org/api/iterator"
33
+ kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
34
+ fieldmask "google.golang.org/genproto/protobuf/field_mask"
29
35
)
30
36
31
37
const (
@@ -77,7 +83,8 @@ var _ = Describe("GCE PD CSI Driver", func() {
77
83
}()
78
84
79
85
// Attach Disk
80
- testAttachWriteReadDetach (volID , volName , instance , client , false /* readOnly */ )
86
+ err = testAttachWriteReadDetach (volID , volName , instance , client , false /* readOnly */ )
87
+ Expect (err ).To (BeNil (), "Failed to go through volume lifecycle" )
81
88
82
89
})
83
90
@@ -151,7 +158,8 @@ var _ = Describe("GCE PD CSI Driver", func() {
151
158
}()
152
159
153
160
// Attach Disk
154
- testAttachWriteReadDetach (underSpecifiedID , volName , instance , client , false /* readOnly */ )
161
+ err = testAttachWriteReadDetach (underSpecifiedID , volName , instance , client , false /* readOnly */ )
162
+ Expect (err ).To (BeNil (), "Failed to go through volume lifecycle" )
155
163
156
164
})
157
165
@@ -294,6 +302,163 @@ var _ = Describe("GCE PD CSI Driver", func() {
294
302
}()
295
303
})
296
304
305
+ It ("Should create CMEK key, go through volume lifecycle, validate behavior on key revoke and restore" , func () {
306
+ ctx := context .Background ()
307
+ Expect (testContexts ).ToNot (BeEmpty ())
308
+ testContext := getRandomTestContext ()
309
+
310
+ controllerInstance := testContext .Instance
311
+ controllerClient := testContext .Client
312
+
313
+ p , z , _ := controllerInstance .GetIdentity ()
314
+ locationID := "global"
315
+
316
+ // The resource name of the key rings.
317
+ parentName := fmt .Sprintf ("projects/%s/locations/%s" , p , locationID )
318
+ keyRingId := "gce-pd-csi-test-ring"
319
+
320
+ // Create KeyRing
321
+ ringReq := & kmspb.CreateKeyRingRequest {
322
+ Parent : parentName ,
323
+ KeyRingId : keyRingId ,
324
+ }
325
+ keyRing , err := kmsClient .CreateKeyRing (ctx , ringReq )
326
+ if ! gce .IsGCEError (err , "alreadyExists" ) {
327
+ getKeyRingReq := & kmspb.GetKeyRingRequest {
328
+ Name : fmt .Sprintf ("%s/keyRings/%s" , parentName , keyRingId ),
329
+ }
330
+ keyRing , err = kmsClient .GetKeyRing (ctx , getKeyRingReq )
331
+
332
+ }
333
+ Expect (err ).To (BeNil (), "Failed to create or get key ring %v" , keyRingId )
334
+
335
+ // Create CryptoKey in KeyRing
336
+ keyId := "test-key-" + string (uuid .NewUUID ())
337
+ keyReq := & kmspb.CreateCryptoKeyRequest {
338
+ Parent : keyRing .Name ,
339
+ CryptoKeyId : keyId ,
340
+ CryptoKey : & kmspb.CryptoKey {
341
+ Purpose : kmspb .CryptoKey_ENCRYPT_DECRYPT ,
342
+ VersionTemplate : & kmspb.CryptoKeyVersionTemplate {
343
+ Algorithm : kmspb .CryptoKeyVersion_GOOGLE_SYMMETRIC_ENCRYPTION ,
344
+ },
345
+ },
346
+ }
347
+ key , err := kmsClient .CreateCryptoKey (ctx , keyReq )
348
+ Expect (err ).To (BeNil (), "Failed to create crypto key %v in key ring %v" , keyId , keyRing .Name )
349
+
350
+ keyVersions := []string {}
351
+ keyVersionReq := & kmspb.ListCryptoKeyVersionsRequest {
352
+ Parent : key .Name ,
353
+ }
354
+
355
+ it := kmsClient .ListCryptoKeyVersions (ctx , keyVersionReq )
356
+
357
+ for {
358
+ keyVersion , err := it .Next ()
359
+ if err == iterator .Done {
360
+ break
361
+ }
362
+ Expect (err ).To (BeNil (), "Failed to list crypto key versions" )
363
+
364
+ keyVersions = append (keyVersions , keyVersion .Name )
365
+ }
366
+
367
+ // Defer deletion of all key versions
368
+ // https://cloud.google.com/kms/docs/destroy-restore
369
+ // Temporarily disable revokation of CMEK key because of test infra CI permissions
370
+ /*
371
+ defer func() {
372
+
373
+ for _, keyVersion := range keyVersions {
374
+ destroyKeyReq := &kmspb.DestroyCryptoKeyVersionRequest{
375
+ Name: keyVersion,
376
+ }
377
+ _, err = kmsClient.DestroyCryptoKeyVersion(ctx, destroyKeyReq)
378
+ Expect(err).To(BeNil(), "Failed to destroy crypto key version: %v", keyVersion)
379
+ }
380
+
381
+ }()
382
+ */
383
+
384
+ // Go through volume lifecycle using CMEK-ed PD
385
+ // Create Disk
386
+ volName := testNamePrefix + string (uuid .NewUUID ())
387
+ volID , err := controllerClient .CreateVolume (volName , map [string ]string {
388
+ common .ParameterKeyDiskEncryptionKmsKey : key .Name ,
389
+ }, defaultSizeGb ,
390
+ & csi.TopologyRequirement {
391
+ Requisite : []* csi.Topology {
392
+ {
393
+ Segments : map [string ]string {common .TopologyKeyZone : z },
394
+ },
395
+ },
396
+ })
397
+ Expect (err ).To (BeNil (), "CreateVolume failed with error: %v" , err )
398
+
399
+ // Validate Disk Created
400
+ cloudDisk , err := computeService .Disks .Get (p , z , volName ).Do ()
401
+ Expect (err ).To (BeNil (), "Could not get disk from cloud directly" )
402
+ Expect (cloudDisk .Type ).To (ContainSubstring (standardDiskType ))
403
+ Expect (cloudDisk .Status ).To (Equal (readyState ))
404
+ Expect (cloudDisk .SizeGb ).To (Equal (defaultSizeGb ))
405
+ Expect (cloudDisk .Name ).To (Equal (volName ))
406
+
407
+ defer func () {
408
+ // Delete Disk
409
+ err = controllerClient .DeleteVolume (volID )
410
+ Expect (err ).To (BeNil (), "DeleteVolume failed" )
411
+
412
+ // Validate Disk Deleted
413
+ _ , err = computeService .Disks .Get (p , z , volName ).Do ()
414
+ Expect (gce .IsGCEError (err , "notFound" )).To (BeTrue (), "Expected disk to not be found" )
415
+ }()
416
+
417
+ // Test disk works
418
+ err = testAttachWriteReadDetach (volID , volName , controllerInstance , controllerClient , false /* readOnly */ )
419
+ Expect (err ).To (BeNil (), "Failed to go through volume lifecycle before revoking CMEK key" )
420
+
421
+ // Revoke CMEK key
422
+ // https://cloud.google.com/kms/docs/enable-disable
423
+
424
+ for _ , keyVersion := range keyVersions {
425
+ disableReq := & kmspb.UpdateCryptoKeyVersionRequest {
426
+ CryptoKeyVersion : & kmspb.CryptoKeyVersion {
427
+ Name : keyVersion ,
428
+ State : kmspb .CryptoKeyVersion_DISABLED ,
429
+ },
430
+ UpdateMask : & fieldmask.FieldMask {
431
+ Paths : []string {"state" },
432
+ },
433
+ }
434
+ _ , err = kmsClient .UpdateCryptoKeyVersion (ctx , disableReq )
435
+ Expect (err ).To (BeNil (), "Failed to disable crypto key" )
436
+ }
437
+
438
+ // Make sure attach of PD fails
439
+ err = testAttachWriteReadDetach (volID , volName , controllerInstance , controllerClient , false /* readOnly */ )
440
+ Expect (err ).ToNot (BeNil (), "Volume lifecycle should have failed, but succeeded" )
441
+
442
+ // Restore CMEK key
443
+ for _ , keyVersion := range keyVersions {
444
+ enableReq := & kmspb.UpdateCryptoKeyVersionRequest {
445
+ CryptoKeyVersion : & kmspb.CryptoKeyVersion {
446
+ Name : keyVersion ,
447
+ State : kmspb .CryptoKeyVersion_ENABLED ,
448
+ },
449
+ UpdateMask : & fieldmask.FieldMask {
450
+ Paths : []string {"state" },
451
+ },
452
+ }
453
+ _ , err = kmsClient .UpdateCryptoKeyVersion (ctx , enableReq )
454
+ Expect (err ).To (BeNil (), "Failed to enable crypto key" )
455
+ }
456
+
457
+ // Make sure attach of PD succeeds
458
+ err = testAttachWriteReadDetach (volID , volName , controllerInstance , controllerClient , false /* readOnly */ )
459
+ Expect (err ).To (BeNil (), "Failed to go through volume lifecycle after restoring CMEK key" )
460
+ })
461
+
297
462
It ("Should create and delete snapshot for RePD in two zones " , func () {
298
463
Expect (testContexts ).ToNot (BeEmpty ())
299
464
testContext := getRandomTestContext ()
0 commit comments