diff --git a/e2e/rbd.go b/e2e/rbd.go index 37b592942c1..76928341925 100644 --- a/e2e/rbd.go +++ b/e2e/rbd.go @@ -2872,6 +2872,55 @@ var _ = Describe("RBD", func() { } }) + By("create storageClass with encrypted as false", func() { + err := deleteResource(rbdExamplePath + "storageclass.yaml") + if err != nil { + framework.Failf("failed to delete storageclass: %v", err) + } + err = createRBDStorageClass( + f.ClientSet, + f, + defaultSCName, + nil, + map[string]string{"encrypted": "false"}, + deletePolicy) + if err != nil { + framework.Failf("failed to create storageclass: %v", err) + } + // set up PVC + pvc, err := loadPVC(pvcPath) + if err != nil { + framework.Failf("failed to load PVC: %v", err) + } + pvc.Namespace = f.UniqueName + err = createPVCAndvalidatePV(f.ClientSet, pvc, deployTimeout) + if err != nil { + framework.Failf("failed to create PVC: %v", err) + } + + // validate created backend rbd images + validateRBDImageCount(f, 1, defaultRBDPool) + validateOmapCount(f, 1, rbdType, defaultRBDPool, volumesType) + + // clean up after ourselves + err = deletePVCAndValidatePV(f.ClientSet, pvc, deployTimeout) + if err != nil { + framework.Failf("failed to delete PVC: %v", err) + } + // validate created backend rbd images + validateRBDImageCount(f, 0, defaultRBDPool) + validateOmapCount(f, 0, rbdType, defaultRBDPool, volumesType) + + err = deleteResource(rbdExamplePath + "storageclass.yaml") + if err != nil { + framework.Failf("failed to delete storageclass: %v", err) + } + err = createRBDStorageClass(f.ClientSet, f, defaultSCName, nil, nil, deletePolicy) + if err != nil { + framework.Failf("failed to create storageclass: %v", err) + } + }) + By("validate RBD static FileSystem PVC", func() { err := validateRBDStaticPV(f, appPath, false, false) if err != nil { diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index 56061b2273b..bd00d148f6b 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -191,7 +191,7 @@ func (cs *ControllerServer) parseVolCreateRequest( // get the owner of the PVC which is required for few encryption related operations rbdVol.Owner = k8s.GetOwner(req.GetParameters()) - err = rbdVol.initKMS(ctx, req.GetParameters(), req.GetSecrets()) + err = rbdVol.initKMS(req.GetParameters(), req.GetSecrets()) if err != nil { return nil, status.Error(codes.InvalidArgument, err.Error()) } diff --git a/internal/rbd/encryption.go b/internal/rbd/encryption.go index ea65f14aa87..3d68e80c898 100644 --- a/internal/rbd/encryption.go +++ b/internal/rbd/encryption.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "strconv" "strings" kmsapi "github.com/ceph/ceph-csi/internal/kms" @@ -109,7 +110,7 @@ func (ri *rbdImage) isFileEncrypted() bool { } func IsFileEncrypted(ctx context.Context, volOptions map[string]string) (bool, error) { - _, encType, err := ParseEncryptionOpts(ctx, volOptions, util.EncryptionTypeInvalid) + _, encType, err := ParseEncryptionOpts(volOptions, util.EncryptionTypeInvalid) if err != nil { return false, err } @@ -305,8 +306,8 @@ func (rv *rbdVolume) openEncryptedDevice(ctx context.Context, devicePath string) return mapperFilePath, nil } -func (ri *rbdImage) initKMS(ctx context.Context, volOptions, credentials map[string]string) error { - kmsID, encType, err := ParseEncryptionOpts(ctx, volOptions, rbdDefaultEncryptionType) +func (ri *rbdImage) initKMS(volOptions, credentials map[string]string) error { + kmsID, encType, err := ParseEncryptionOpts(volOptions, rbdDefaultEncryptionType) if err != nil { return err } @@ -331,7 +332,6 @@ func (ri *rbdImage) initKMS(ctx context.Context, volOptions, credentials map[str // ParseEncryptionOpts returns kmsID and sets Owner attribute. func ParseEncryptionOpts( - ctx context.Context, volOptions map[string]string, fallbackEncType util.EncryptionType, ) (string, util.EncryptionType, error) { @@ -344,6 +344,13 @@ func ParseEncryptionOpts( if !ok { return "", util.EncryptionTypeNone, nil } + ok, err = strconv.ParseBool(encrypted) + if err != nil { + return "", util.EncryptionTypeInvalid, err + } + if !ok { + return "", util.EncryptionTypeNone, nil + } kmsID, err = util.FetchEncryptionKMSID(encrypted, volOptions["encryptionKMSID"]) if err != nil { return "", util.EncryptionTypeInvalid, err diff --git a/internal/rbd/encryption_test.go b/internal/rbd/encryption_test.go new file mode 100644 index 00000000000..fb043050ad2 --- /dev/null +++ b/internal/rbd/encryption_test.go @@ -0,0 +1,99 @@ +/* +Copyright 2023 The Ceph-CSI Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package rbd + +import ( + "testing" + + "github.com/ceph/ceph-csi/internal/util" +) + +func TestParseEncryptionOpts(t *testing.T) { + t.Parallel() + tests := []struct { + testName string + volOptions map[string]string + fallbackType util.EncryptionType + expectedKMS string + expectedEnc util.EncryptionType + expectedErr bool + }{ + { + testName: "No Encryption Option", + volOptions: map[string]string{ + "foo": "bar", + }, + fallbackType: util.EncryptionTypeBlock, + expectedKMS: "", + expectedEnc: util.EncryptionTypeNone, + expectedErr: false, + }, + { + testName: "Encrypted as false", + volOptions: map[string]string{ + "encrypted": "false", + }, + fallbackType: util.EncryptionTypeBlock, + expectedKMS: "", + expectedEnc: util.EncryptionTypeNone, + expectedErr: false, + }, + { + testName: "Encrypted as invalid string", + volOptions: map[string]string{ + "encrypted": "notbool", + }, + fallbackType: util.EncryptionTypeBlock, + expectedKMS: "", + expectedEnc: util.EncryptionTypeInvalid, + expectedErr: true, + }, + { + testName: "Valid Encryption Option With KMS ID", + volOptions: map[string]string{ + "encrypted": "true", + "encryptionKMSID": "valid-kms-id", + }, + fallbackType: util.EncryptionTypeBlock, + expectedKMS: "valid-kms-id", + expectedEnc: util.EncryptionTypeBlock, + expectedErr: false, + }, + } + + for _, tt := range tests { + newtt := tt + t.Run(newtt.testName, func(t *testing.T) { + t.Parallel() + actualKMS, actualEnc, actualErr := ParseEncryptionOpts( + newtt.volOptions, + newtt.fallbackType, + ) + if actualKMS != newtt.expectedKMS { + t.Errorf("Expected KMS ID: %s, but got: %s", newtt.expectedKMS, actualKMS) + } + + if actualEnc != newtt.expectedEnc { + t.Errorf("Expected Encryption Type: %v, but got: %v", newtt.expectedEnc, actualEnc) + } + + if (actualErr != nil) != newtt.expectedErr { + t.Errorf("expected error %v but got %v", newtt.expectedErr, actualErr) + } + }) + } +} diff --git a/internal/rbd/nodeserver.go b/internal/rbd/nodeserver.go index 22efcf90162..825f9bc61a7 100644 --- a/internal/rbd/nodeserver.go +++ b/internal/rbd/nodeserver.go @@ -234,7 +234,7 @@ func (ns *NodeServer) populateRbdVol( return nil, status.Error(codes.Internal, err.Error()) } - err = rv.initKMS(ctx, req.GetVolumeContext(), req.GetSecrets()) + err = rv.initKMS(req.GetVolumeContext(), req.GetSecrets()) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } diff --git a/internal/rbd/rbd_journal.go b/internal/rbd/rbd_journal.go index 49bb241b312..55c6a033ebf 100644 --- a/internal/rbd/rbd_journal.go +++ b/internal/rbd/rbd_journal.go @@ -573,7 +573,7 @@ func RegenerateJournal( rbdVol.Owner = owner - kmsID, encryptionType, err = ParseEncryptionOpts(ctx, volumeAttributes, util.EncryptionTypeNone) + kmsID, encryptionType, err = ParseEncryptionOpts(volumeAttributes, util.EncryptionTypeNone) if err != nil { return "", err }