From 7b5c78ec7c36b98433d19956efba2bf061dc3428 Mon Sep 17 00:00:00 2001 From: Madhu Rajanna Date: Tue, 1 Jun 2021 17:03:29 +0530 Subject: [PATCH] rbd: fail fast in create volume for missmatch encryption CreateVolume will fail in below cases * If the snapshot is encrypted and requested volume is not encrypted * If the snapshot is not encrypted and requested volume is encrypted * If the parent volume is encrypted and requested volume is not encrypted * If the parent volume is not encrypted and requested volume is encrypted Signed-off-by: Madhu Rajanna --- internal/rbd/controllerserver.go | 23 ++++++++++++++++++++++- internal/rbd/rbd_util.go | 12 ++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index 18c622846..c657c3439 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -210,6 +210,27 @@ func validateRequestedVolumeSize(rbdVol, parentVol *rbdVolume, rbdSnap *rbdSnaps return nil } +func checkValidCreateVolumeRequest(rbdVol, parentVol *rbdVolume, rbdSnap *rbdSnapshot, cr *util.Credentials) error { + err := validateRequestedVolumeSize(rbdVol, parentVol, rbdSnap, cr) + if err != nil { + return err + } + + switch { + case rbdSnap != nil: + err = rbdSnap.isCompatibleEncryption(&rbdVol.rbdImage) + if err != nil { + return status.Errorf(codes.InvalidArgument, "cannot restore from snapshot %s: %s", rbdSnap, err.Error()) + } + case parentVol != nil: + err = parentVol.isCompatibleEncryption(&rbdVol.rbdImage) + if err != nil { + return status.Errorf(codes.InvalidArgument, "cannot clone from volume %s: %s", parentVol, err.Error()) + } + } + return nil +} + // CreateVolume creates the volume in backend. func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) { if err := cs.validateVolumeReq(ctx, req); err != nil { @@ -254,7 +275,7 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol return cs.repairExistingVolume(ctx, req, cr, rbdVol, rbdSnap) } - err = validateRequestedVolumeSize(rbdVol, parentVol, rbdSnap, cr) + err = checkValidCreateVolumeRequest(rbdVol, parentVol, rbdSnap, cr) if err != nil { return nil, err } diff --git a/internal/rbd/rbd_util.go b/internal/rbd/rbd_util.go index ab6e313c1..c11c6468b 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -1528,3 +1528,15 @@ func (rv *rbdVolume) getOrigSnapName(snapID uint64) (string, error) { return origSnapName, nil } + +func (ri *rbdImage) isCompatibleEncryption(dst *rbdImage) error { + switch { + case ri.isEncrypted() && !dst.isEncrypted(): + return fmt.Errorf("encrypted volume %q does not match unencrypted volume %q", ri, dst) + + case !ri.isEncrypted() && dst.isEncrypted(): + return fmt.Errorf("unencrypted volume %q does not match encrypted volume %q", ri, dst) + } + + return nil +}