-
Notifications
You must be signed in to change notification settings - Fork 159
Add CMEK E2E Test #218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CMEK E2E Test #218
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,8 @@ limitations under the License. | |
package tests | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strings" | ||
"time" | ||
|
||
|
@@ -26,6 +28,10 @@ import ( | |
csi "github.com/container-storage-interface/spec/lib/go/csi" | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
|
||
"google.golang.org/api/iterator" | ||
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1" | ||
fieldmask "google.golang.org/genproto/protobuf/field_mask" | ||
) | ||
|
||
const ( | ||
|
@@ -78,7 +84,8 @@ var _ = Describe("GCE PD CSI Driver", func() { | |
}() | ||
|
||
// Attach Disk | ||
testAttachWriteReadDetach(volID, volName, instance, client, false /* readOnly */) | ||
err = testAttachWriteReadDetach(volID, volName, instance, client, false /* readOnly */) | ||
Expect(err).To(BeNil(), "Failed to go through volume lifecycle") | ||
|
||
}) | ||
|
||
|
@@ -152,7 +159,8 @@ var _ = Describe("GCE PD CSI Driver", func() { | |
}() | ||
|
||
// Attach Disk | ||
testAttachWriteReadDetach(underSpecifiedID, volName, instance, client, false /* readOnly */) | ||
err = testAttachWriteReadDetach(underSpecifiedID, volName, instance, client, false /* readOnly */) | ||
Expect(err).To(BeNil(), "Failed to go through volume lifecycle") | ||
|
||
}) | ||
|
||
|
@@ -295,6 +303,160 @@ var _ = Describe("GCE PD CSI Driver", func() { | |
}() | ||
}) | ||
|
||
It("Should create CMEK key, go through volume lifecycle, validate behavior on key revoke and restore", func() { | ||
ctx := context.Background() | ||
Expect(testContexts).ToNot(BeEmpty()) | ||
testContext := getRandomTestContext() | ||
|
||
controllerInstance := testContext.Instance | ||
controllerClient := testContext.Client | ||
|
||
p, z, _ := controllerInstance.GetIdentity() | ||
locationID := "global" | ||
|
||
// The resource name of the key rings. | ||
parentName := fmt.Sprintf("projects/%s/locations/%s", p, locationID) | ||
keyRingId := "gce-pd-csi-test-ring" | ||
|
||
// Create KeyRing | ||
ringReq := &kmspb.CreateKeyRingRequest{ | ||
Parent: parentName, | ||
KeyRingId: keyRingId, | ||
} | ||
keyRing, err := kmsClient.CreateKeyRing(ctx, ringReq) | ||
if !gce.IsGCEError(err, "alreadyExists") { | ||
getKeyRingReq := &kmspb.GetKeyRingRequest{ | ||
Name: fmt.Sprintf("%s/keyRings/%s", parentName, keyRingId), | ||
} | ||
keyRing, err = kmsClient.GetKeyRing(ctx, getKeyRingReq) | ||
|
||
} | ||
Expect(err).To(BeNil(), "Failed to create or get key ring %v", keyRingId) | ||
|
||
// Create CryptoKey in KeyRing | ||
keyId := "test-key-" + string(uuid.NewUUID()) | ||
keyReq := &kmspb.CreateCryptoKeyRequest{ | ||
Parent: keyRing.Name, | ||
CryptoKeyId: keyId, | ||
CryptoKey: &kmspb.CryptoKey{ | ||
Purpose: kmspb.CryptoKey_ENCRYPT_DECRYPT, | ||
VersionTemplate: &kmspb.CryptoKeyVersionTemplate{ | ||
Algorithm: kmspb.CryptoKeyVersion_GOOGLE_SYMMETRIC_ENCRYPTION, | ||
}, | ||
}, | ||
} | ||
key, err := kmsClient.CreateCryptoKey(ctx, keyReq) | ||
Expect(err).To(BeNil(), "Failed to create crypto key %v in key ring %v", keyId, keyRing.Name) | ||
|
||
keyVersions := []string{} | ||
keyVersionReq := &kmspb.ListCryptoKeyVersionsRequest{ | ||
Parent: key.Name, | ||
} | ||
|
||
it := kmsClient.ListCryptoKeyVersions(ctx, keyVersionReq) | ||
|
||
for { | ||
keyVersion, err := it.Next() | ||
if err == iterator.Done { | ||
break | ||
} | ||
Expect(err).To(BeNil(), "Failed to list crypto key versions") | ||
|
||
keyVersions = append(keyVersions, keyVersion.Name) | ||
} | ||
|
||
// Defer deletion of all key versions | ||
// https://cloud.google.com/kms/docs/destroy-restore | ||
defer func() { | ||
|
||
for _, keyVersion := range keyVersions { | ||
destroyKeyReq := &kmspb.DestroyCryptoKeyVersionRequest{ | ||
Name: keyVersion, | ||
} | ||
_, err = kmsClient.DestroyCryptoKeyVersion(ctx, destroyKeyReq) | ||
Expect(err).To(BeNil(), "Failed to destroy crypto key version: %v", keyVersion) | ||
} | ||
|
||
}() | ||
|
||
// Go through volume lifecycle using CMEK-ed PD | ||
// Create Disk | ||
volName := testNamePrefix + string(uuid.NewUUID()) | ||
volID, err := controllerClient.CreateVolume(volName, map[string]string{ | ||
common.ParameterKeyDiskEncryptionKmsKey: key.Name, | ||
}, defaultSizeGb, | ||
&csi.TopologyRequirement{ | ||
Requisite: []*csi.Topology{ | ||
{ | ||
Segments: map[string]string{common.TopologyKeyZone: z}, | ||
}, | ||
}, | ||
}) | ||
Expect(err).To(BeNil(), "CreateVolume failed with error: %v", err) | ||
|
||
// Validate Disk Created | ||
cloudDisk, err := computeService.Disks.Get(p, z, volName).Do() | ||
Expect(err).To(BeNil(), "Could not get disk from cloud directly") | ||
Expect(cloudDisk.Type).To(ContainSubstring(standardDiskType)) | ||
Expect(cloudDisk.Status).To(Equal(readyState)) | ||
Expect(cloudDisk.SizeGb).To(Equal(defaultSizeGb)) | ||
Expect(cloudDisk.Name).To(Equal(volName)) | ||
|
||
defer func() { | ||
// Delete Disk | ||
err = controllerClient.DeleteVolume(volID) | ||
Expect(err).To(BeNil(), "DeleteVolume failed") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is err coming from? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. previous line but it got lost somehow |
||
|
||
// Validate Disk Deleted | ||
_, err = computeService.Disks.Get(p, z, volName).Do() | ||
Expect(gce.IsGCEError(err, "notFound")).To(BeTrue(), "Expected disk to not be found") | ||
}() | ||
|
||
// Test disk works | ||
err = testAttachWriteReadDetach(volID, volName, controllerInstance, controllerClient, false /* readOnly */) | ||
Expect(err).To(BeNil(), "Failed to go through volume lifecycle before revoking CMEK key") | ||
|
||
// Revoke CMEK key | ||
// https://cloud.google.com/kms/docs/enable-disable | ||
|
||
for _, keyVersion := range keyVersions { | ||
disableReq := &kmspb.UpdateCryptoKeyVersionRequest{ | ||
CryptoKeyVersion: &kmspb.CryptoKeyVersion{ | ||
Name: keyVersion, | ||
State: kmspb.CryptoKeyVersion_DISABLED, | ||
}, | ||
UpdateMask: &fieldmask.FieldMask{ | ||
Paths: []string{"state"}, | ||
}, | ||
} | ||
_, err = kmsClient.UpdateCryptoKeyVersion(ctx, disableReq) | ||
Expect(err).To(BeNil(), "Failed to disable crypto key") | ||
} | ||
|
||
// Make sure attach of PD fails | ||
err = testAttachWriteReadDetach(volID, volName, controllerInstance, controllerClient, false /* readOnly */) | ||
Expect(err).ToNot(BeNil(), "Volume lifecycle should have failed, but succeeded") | ||
|
||
// Restore CMEK key | ||
for _, keyVersion := range keyVersions { | ||
enableReq := &kmspb.UpdateCryptoKeyVersionRequest{ | ||
CryptoKeyVersion: &kmspb.CryptoKeyVersion{ | ||
Name: keyVersion, | ||
State: kmspb.CryptoKeyVersion_ENABLED, | ||
}, | ||
UpdateMask: &fieldmask.FieldMask{ | ||
Paths: []string{"state"}, | ||
}, | ||
} | ||
_, err = kmsClient.UpdateCryptoKeyVersion(ctx, enableReq) | ||
Expect(err).To(BeNil(), "Failed to enable crypto key") | ||
} | ||
|
||
// Make sure attach of PD succeeds | ||
err = testAttachWriteReadDetach(volID, volName, controllerInstance, controllerClient, false /* readOnly */) | ||
Expect(err).To(BeNil(), "Failed to go through volume lifecycle after restoring CMEK key") | ||
}) | ||
|
||
It("Should create and delete snapshot for RePD in two zones ", func() { | ||
Expect(testContexts).ToNot(BeEmpty()) | ||
testContext := getRandomTestContext() | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any possible issue of multiple tests sharing the same key ring? Or leaving a key ring around at the end of the test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
key ring resource names are immutable.. all the tests will share the same key ring and the key ring will exist for the forseeable future. Talked to the CMEK TL and this is intended behavior