@@ -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,158 @@ 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
+ defer func () {
370
+ for _ , keyVersion := range keyVersions {
371
+ destroyKeyReq := & kmspb.DestroyCryptoKeyVersionRequest {
372
+ Name : keyVersion ,
373
+ }
374
+ _ , err = kmsClient .DestroyCryptoKeyVersion (ctx , destroyKeyReq )
375
+ Expect (err ).To (BeNil (), "Failed to destroy crypto key version: %v" , keyVersion )
376
+ }
377
+
378
+ }()
379
+
380
+ // Go through volume lifecycle using CMEK-ed PD
381
+ // Create Disk
382
+ volName := testNamePrefix + string (uuid .NewUUID ())
383
+ volID , err := controllerClient .CreateVolume (volName , map [string ]string {
384
+ common .ParameterKeyDiskEncryptionKmsKey : key .Name ,
385
+ }, defaultSizeGb ,
386
+ & csi.TopologyRequirement {
387
+ Requisite : []* csi.Topology {
388
+ {
389
+ Segments : map [string ]string {common .TopologyKeyZone : z },
390
+ },
391
+ },
392
+ })
393
+ Expect (err ).To (BeNil (), "CreateVolume failed with error: %v" , err )
394
+
395
+ // Validate Disk Created
396
+ cloudDisk , err := computeService .Disks .Get (p , z , volName ).Do ()
397
+ Expect (err ).To (BeNil (), "Could not get disk from cloud directly" )
398
+ Expect (cloudDisk .Type ).To (ContainSubstring (standardDiskType ))
399
+ Expect (cloudDisk .Status ).To (Equal (readyState ))
400
+ Expect (cloudDisk .SizeGb ).To (Equal (defaultSizeGb ))
401
+ Expect (cloudDisk .Name ).To (Equal (volName ))
402
+
403
+ defer func () {
404
+ // Delete Disk
405
+ err = controllerClient .DeleteVolume (volID )
406
+ Expect (err ).To (BeNil (), "DeleteVolume failed" )
407
+
408
+ // Validate Disk Deleted
409
+ _ , err = computeService .Disks .Get (p , z , volName ).Do ()
410
+ Expect (gce .IsGCEError (err , "notFound" )).To (BeTrue (), "Expected disk to not be found" )
411
+ }()
412
+
413
+ // Test disk works
414
+ err = testAttachWriteReadDetach (volID , volName , controllerInstance , controllerClient , false /* readOnly */ )
415
+ Expect (err ).To (BeNil (), "Failed to go through volume lifecycle before revoking CMEK key" )
416
+
417
+ // Revoke CMEK key
418
+ // https://cloud.google.com/kms/docs/enable-disable
419
+ for _ , keyVersion := range keyVersions {
420
+ disableReq := & kmspb.UpdateCryptoKeyVersionRequest {
421
+ CryptoKeyVersion : & kmspb.CryptoKeyVersion {
422
+ Name : keyVersion ,
423
+ State : kmspb .CryptoKeyVersion_DISABLED ,
424
+ },
425
+ UpdateMask : & fieldmask.FieldMask {
426
+ Paths : []string {"state" },
427
+ },
428
+ }
429
+ _ , err = kmsClient .UpdateCryptoKeyVersion (ctx , disableReq )
430
+ Expect (err ).To (BeNil (), "Failed to disable crypto key" )
431
+ }
432
+
433
+ // Make sure attach of PD fails
434
+ err = testAttachWriteReadDetach (volID , volName , controllerInstance , controllerClient , false /* readOnly */ )
435
+ Expect (err ).ToNot (BeNil (), "Volume lifecycle should have failed, but succeeded" )
436
+
437
+ // Restore CMEK key
438
+ for _ , keyVersion := range keyVersions {
439
+ enableReq := & kmspb.UpdateCryptoKeyVersionRequest {
440
+ CryptoKeyVersion : & kmspb.CryptoKeyVersion {
441
+ Name : keyVersion ,
442
+ State : kmspb .CryptoKeyVersion_ENABLED ,
443
+ },
444
+ UpdateMask : & fieldmask.FieldMask {
445
+ Paths : []string {"state" },
446
+ },
447
+ }
448
+ _ , err = kmsClient .UpdateCryptoKeyVersion (ctx , enableReq )
449
+ Expect (err ).To (BeNil (), "Failed to enable crypto key" )
450
+ }
451
+
452
+ // Make sure attach of PD succeeds
453
+ err = testAttachWriteReadDetach (volID , volName , controllerInstance , controllerClient , false /* readOnly */ )
454
+ Expect (err ).To (BeNil (), "Failed to go through volume lifecycle after restoring CMEK key" )
455
+ })
456
+
297
457
It ("Should create and delete snapshot for RePD in two zones " , func () {
298
458
Expect (testContexts ).ToNot (BeEmpty ())
299
459
testContext := getRandomTestContext ()
0 commit comments