diff --git a/e2e/rbd.go b/e2e/rbd.go index b92ee0ca5..4c42067cf 100644 --- a/e2e/rbd.go +++ b/e2e/rbd.go @@ -745,7 +745,37 @@ var _ = Describe("RBD", func() { By("create a PVC-PVC clone and bind it to an app", func() { // pvc clone is only supported from v1.16+ if k8sVersionGreaterEquals(f.ClientSet, 1, 16) { - validatePVCClone(pvcPath, appPath, pvcSmartClonePath, appSmartClonePath, f) + validatePVCClone(pvcPath, appPath, pvcSmartClonePath, appSmartClonePath, false, f) + } + }) + + By("create an encrypted PVC-PVC clone and bind it to an app", func() { + if !k8sVersionGreaterEquals(f.ClientSet, 1, 16) { + Skip("pvc clone is only supported from v1.16+") + } + + err := deleteResource(rbdExamplePath + "storageclass.yaml") + if err != nil { + e2elog.Failf("failed to delete storageclass with error %v", err) + } + scOpts := map[string]string{ + "encrypted": "true", + "encryptionKMSID": "secrets-metadata-test", + } + err = createRBDStorageClass(f.ClientSet, f, nil, scOpts, deletePolicy) + if err != nil { + e2elog.Failf("failed to create storageclass with error %v", err) + } + + validatePVCClone(pvcPath, appPath, pvcSmartClonePath, appSmartClonePath, true, f) + + err = deleteResource(rbdExamplePath + "storageclass.yaml") + if err != nil { + e2elog.Failf("failed to delete storageclass with error %v", err) + } + err = createRBDStorageClass(f.ClientSet, f, nil, nil, deletePolicy) + if err != nil { + e2elog.Failf("failed to create storageclass with error %v", err) } }) @@ -762,7 +792,7 @@ var _ = Describe("RBD", func() { } // pvc clone is only supported from v1.16+ if v.Major > "1" || (v.Major == "1" && v.Minor >= "16") { - validatePVCClone(rawPvcPath, rawAppPath, pvcBlockSmartClonePath, appBlockSmartClonePath, f) + validatePVCClone(rawPvcPath, rawAppPath, pvcBlockSmartClonePath, appBlockSmartClonePath, false, f) } }) By("create/delete multiple PVCs and Apps", func() { diff --git a/e2e/rbd_helper.go b/e2e/rbd_helper.go index c76923ddb..05093fee0 100644 --- a/e2e/rbd_helper.go +++ b/e2e/rbd_helper.go @@ -238,23 +238,12 @@ func validateEncryptedPVCAndAppBinding(pvcPath, appPath, kms string, f *framewor if err != nil { return err } - rbdImageSpec := imageSpec(defaultRBDPool, imageData.imageName) - encryptedState, err := getImageMeta(rbdImageSpec, ".rbd.csi.ceph.com/encrypted", f) - if err != nil { - return err - } - if encryptedState != "encrypted" { - return fmt.Errorf("%v not equal to encrypted", encryptedState) - } - volumeMountPath := app.Spec.Containers[0].VolumeMounts[0].MountPath - mountType, err := getMountType(app.Name, app.Namespace, volumeMountPath, f) + rbdImageSpec := imageSpec(defaultRBDPool, imageData.imageName) + err = validateEncryptedImage(f, rbdImageSpec, app) if err != nil { return err } - if mountType != "crypt" { - return fmt.Errorf("%v not equal to crypt", mountType) - } if kmsIsVault(kms) || kms == "vaulttokens" { // check new passphrase created @@ -279,6 +268,41 @@ func validateEncryptedPVCAndAppBinding(pvcPath, appPath, kms string, f *framewor return nil } +func validateEncryptedPVC(f *framework.Framework, pvc *v1.PersistentVolumeClaim, app *v1.Pod) error { + imageData, err := getImageInfoFromPVC(pvc.Namespace, pvc.Name, f) + if err != nil { + return err + } + rbdImageSpec := imageSpec(defaultRBDPool, imageData.imageName) + + return validateEncryptedImage(f, rbdImageSpec, app) +} + +// validateEncryptedImage verifies that the RBD image is encrypted. The +// following checks are performed: +// - Metadata of the image should be set with the encryption state; +// - The pvc should be mounted by a pod, so the filesystem type can be fetched. +func validateEncryptedImage(f *framework.Framework, rbdImageSpec string, app *v1.Pod) error { + encryptedState, err := getImageMeta(rbdImageSpec, ".rbd.csi.ceph.com/encrypted", f) + if err != nil { + return err + } + if encryptedState != "encrypted" { + return fmt.Errorf("%v not equal to encrypted", encryptedState) + } + + volumeMountPath := app.Spec.Containers[0].VolumeMounts[0].MountPath + mountType, err := getMountType(app.Name, app.Namespace, volumeMountPath, f) + if err != nil { + return err + } + if mountType != "crypt" { + return fmt.Errorf("%v not equal to crypt", mountType) + } + + return nil +} + func listRBDImages(f *framework.Framework) ([]string, error) { var imgInfos []string diff --git a/e2e/utils.go b/e2e/utils.go index 9b658d20c..8a8f023c3 100644 --- a/e2e/utils.go +++ b/e2e/utils.go @@ -504,8 +504,8 @@ func writeDataAndCalChecksum(app *v1.Pod, opt *metav1.ListOptions, f *framework. return checkSum, nil } -// nolint:gocyclo // reduce complexity -func validatePVCClone(sourcePvcPath, sourceAppPath, clonePvcPath, clonePvcAppPath string, f *framework.Framework) { +// nolint:gocyclo,gocognit // reduce complexity +func validatePVCClone(sourcePvcPath, sourceAppPath, clonePvcPath, clonePvcAppPath string, validateEncryption bool, f *framework.Framework) { var wg sync.WaitGroup totalCount := 10 wgErrs := make([]error, totalCount) @@ -582,6 +582,9 @@ func validatePVCClone(sourcePvcPath, sourceAppPath, clonePvcPath, clonePvcAppPat e2elog.Logf("checksum didn't match. checksum=%s and checksumclone=%s", checkSum, checkSumClone) } } + if wgErrs[n] == nil && validateEncryption { + wgErrs[n] = validateEncryptedPVC(f, &p, &a) + } w.Done() }(&wg, i, *pvcClone, *appClone) }