From ce9fbb3474bcd182d5da3df6544fd2cf3fa08ceb Mon Sep 17 00:00:00 2001 From: Marcel Lauhoff Date: Fri, 27 May 2022 20:03:32 +0200 Subject: [PATCH] rbd: Rename encryption to blockEncryption prep for fscrypt In preparation of fscrypt support for RBD filesystems, rename block encryption related function to include the word 'block'. Add struct fields and IsFileEncrypted. Signed-off-by: Marcel Lauhoff --- internal/rbd/controllerserver.go | 2 +- internal/rbd/encryption.go | 47 ++++++++++++++++++-------------- internal/rbd/nodeserver.go | 16 +++++------ internal/rbd/rbd_attach.go | 2 +- internal/rbd/rbd_journal.go | 12 ++++---- internal/rbd/rbd_util.go | 32 +++++++++++++--------- internal/rbd/snapshot.go | 2 +- 7 files changed, 62 insertions(+), 51 deletions(-) diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index bf57b8857..0ed109ae4 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -1560,7 +1560,7 @@ func (cs *ControllerServer) ControllerExpandVolume( // 2. Block VolumeMode with Encryption // Hence set nodeExpansion flag based on VolumeMode and Encryption status nodeExpansion := true - if req.GetVolumeCapability().GetBlock() != nil && !rbdVol.isEncrypted() { + if req.GetVolumeCapability().GetBlock() != nil && !rbdVol.isBlockEncrypted() { nodeExpansion = false } diff --git a/internal/rbd/encryption.go b/internal/rbd/encryption.go index 4afd8b4f7..60522504f 100644 --- a/internal/rbd/encryption.go +++ b/internal/rbd/encryption.go @@ -93,16 +93,21 @@ func (ri *rbdImage) ensureEncryptionMetadataSet(status rbdEncryptionState) error return nil } -// isEncrypted returns `true` if the rbdImage is (or needs to be) encrypted. -func (ri *rbdImage) isEncrypted() bool { - return ri.encryption != nil +// isBlockEncrypted returns `true` if the rbdImage is (or needs to be) encrypted. +func (ri *rbdImage) isBlockEncrypted() bool { + return ri.blockEncryption != nil } -// setupEncryption configures the metadata of the RBD image for encryption: +// isBlockDeviceEncrypted returns `true` if the filesystem on the rbdImage is (or needs to be) encrypted. +func (ri *rbdImage) isFileEncrypted() bool { + return ri.fileEncryption != nil +} + +// setupBlockEncryption configures the metadata of the RBD image for encryption: // - the Data-Encryption-Key (DEK) will be generated stored for use by the KMS; // - the RBD image will be marked to support encryption in its metadata. -func (ri *rbdImage) setupEncryption(ctx context.Context) error { - err := ri.encryption.StoreNewCryptoPassphrase(ri.VolID, encryptionPassphraseSize) +func (ri *rbdImage) setupBlockEncryption(ctx context.Context) error { + err := ri.blockEncryption.StoreNewCryptoPassphrase(ri.VolID, encryptionPassphraseSize) if err != nil { log.ErrorLog(ctx, "failed to save encryption passphrase for "+ "image %s: %s", ri, err) @@ -132,7 +137,7 @@ func (ri *rbdImage) setupEncryption(ctx context.Context) error { // (Usecase: Restoring snapshot into a storageclass with different encryption config). func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool) error { // nothing to do if parent image is not encrypted. - if !ri.isEncrypted() { + if !ri.isBlockEncrypted() { return nil } @@ -142,21 +147,21 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool) } // get the unencrypted passphrase - passphrase, err := ri.encryption.GetCryptoPassphrase(ri.VolID) + passphrase, err := ri.blockEncryption.GetCryptoPassphrase(ri.VolID) if err != nil { return fmt.Errorf("failed to fetch passphrase for %q: %w", ri, err) } if !copyOnlyPassphrase { - cp.encryption, err = util.NewVolumeEncryption(ri.encryption.GetID(), ri.encryption.KMS) + cp.blockEncryption, err = util.NewVolumeEncryption(ri.blockEncryption.GetID(), ri.blockEncryption.KMS) if errors.Is(err, util.ErrDEKStoreNeeded) { - cp.encryption.SetDEKStore(cp) + cp.blockEncryption.SetDEKStore(cp) } } // re-encrypt the plain passphrase for the cloned volume - err = cp.encryption.StoreCryptoPassphrase(cp.VolID, passphrase) + err = cp.blockEncryption.StoreCryptoPassphrase(cp.VolID, passphrase) if err != nil { return fmt.Errorf("failed to store passphrase for %q: %w", cp, err) @@ -180,12 +185,12 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool) // repairEncryptionConfig checks the encryption state of the current rbdImage, // and makes sure that the destination rbdImage has the same configuration. func (ri *rbdImage) repairEncryptionConfig(dest *rbdImage) error { - if !ri.isEncrypted() { + if !ri.isBlockEncrypted() { return nil } // if ri is encrypted, copy its configuration in case it is missing - if !dest.isEncrypted() { + if !dest.isBlockEncrypted() { // dest needs to be connected to the cluster, otherwise it will // not be possible to write any metadata if dest.conn == nil { @@ -199,7 +204,7 @@ func (ri *rbdImage) repairEncryptionConfig(dest *rbdImage) error { } func (ri *rbdImage) encryptDevice(ctx context.Context, devicePath string) error { - passphrase, err := ri.encryption.GetCryptoPassphrase(ri.VolID) + passphrase, err := ri.blockEncryption.GetCryptoPassphrase(ri.VolID) if err != nil { log.ErrorLog(ctx, "failed to get crypto passphrase for %s: %v", ri, err) @@ -225,7 +230,7 @@ func (ri *rbdImage) encryptDevice(ctx context.Context, devicePath string) error } func (rv *rbdVolume) openEncryptedDevice(ctx context.Context, devicePath string) (string, error) { - passphrase, err := rv.encryption.GetCryptoPassphrase(rv.VolID) + passphrase, err := rv.blockEncryption.GetCryptoPassphrase(rv.VolID) if err != nil { log.ErrorLog(ctx, "failed to get passphrase for encrypted device %s: %v", rv, err) @@ -264,7 +269,7 @@ func (ri *rbdImage) initKMS(ctx context.Context, volOptions, credentials map[str return nil } - err = ri.configureEncryption(kmsID, credentials) + err = ri.configureBlockDeviceEncryption(kmsID, credentials) if err != nil { return fmt.Errorf("invalid encryption kms configuration: %w", err) } @@ -294,20 +299,20 @@ func (ri *rbdImage) ParseEncryptionOpts( return kmsID, nil } -// configureEncryption sets up the VolumeEncryption for this rbdImage. Once -// configured, use isEncrypted() to see if the volume supports encryption. -func (ri *rbdImage) configureEncryption(kmsID string, credentials map[string]string) error { +// configureBlockDeviceEncryption sets up the VolumeEncryption for this rbdImage. Once +// configured, use isBlockEncrypted() to see if the volume supports block encryption. +func (ri *rbdImage) configureBlockEncryption(kmsID string, credentials map[string]string) error { kms, err := kmsapi.GetKMS(ri.Owner, kmsID, credentials) if err != nil { return err } - ri.encryption, err = util.NewVolumeEncryption(kmsID, kms) + ri.blockEncryption, err = util.NewVolumeEncryption(kmsID, kms) // if the KMS can not store the DEK itself, we'll store it in the // metadata of the RBD image itself if errors.Is(err, util.ErrDEKStoreNeeded) { - ri.encryption.SetDEKStore(ri) + ri.blockEncryption.SetDEKStore(ri) } return nil diff --git a/internal/rbd/nodeserver.go b/internal/rbd/nodeserver.go index 9b8c17fa3..13ae40663 100644 --- a/internal/rbd/nodeserver.go +++ b/internal/rbd/nodeserver.go @@ -55,8 +55,8 @@ type stageTransaction struct { isStagePathCreated bool // isMounted represents if the volume was mounted or not isMounted bool - // isEncrypted represents if the volume was encrypted or not - isEncrypted bool + // isBlockEncrypted represents if the volume was encrypted or not + isBlockEncrypted bool // devicePath represents the path where rbd device is mapped devicePath string } @@ -425,12 +425,12 @@ func (ns *NodeServer) stageTransaction( } } - if volOptions.isEncrypted() { + if volOptions.isBlockEncrypted() { devicePath, err = ns.processEncryptedDevice(ctx, volOptions, devicePath) if err != nil { return transaction, err } - transaction.isEncrypted = true + transaction.isBlockEncrypted = true } stagingTargetPath := getStagingTargetPath(req) @@ -475,13 +475,13 @@ func resizeNodeStagePath(ctx context.Context, var ok bool // if its a non encrypted block device we dont need any expansion - if isBlock && !transaction.isEncrypted { + if isBlock && !transaction.isBlockEncrypted { return nil } resizer := mount.NewResizeFs(utilexec.New()) - if transaction.isEncrypted { + if transaction.isBlockEncrypted { devicePath, err = resizeEncryptedDevice(ctx, volID, stagingTargetPath, devicePath) if err != nil { return status.Error(codes.Internal, err.Error()) @@ -611,7 +611,7 @@ func (ns *NodeServer) undoStagingTransaction( // Unmapping rbd device if transaction.devicePath != "" { - err = detachRBDDevice(ctx, transaction.devicePath, volID, volOptions.UnmapOptions, transaction.isEncrypted) + err = detachRBDDevice(ctx, transaction.devicePath, volID, volOptions.UnmapOptions, transaction.isBlockEncrypted) if err != nil { log.ErrorLog( ctx, @@ -1146,7 +1146,7 @@ func (ns *NodeServer) processEncryptedDevice( // CreateVolume. // Use the same setupEncryption() as CreateVolume does, and // continue with the common process to crypt-format the device. - err = volOptions.setupEncryption(ctx) + err = volOptions.setupBlockEncryption(ctx) if err != nil { log.ErrorLog(ctx, "failed to setup encryption for rbd"+ "image %s: %v", imageSpec, err) diff --git a/internal/rbd/rbd_attach.go b/internal/rbd/rbd_attach.go index ad326ac81..1af3f065b 100644 --- a/internal/rbd/rbd_attach.go +++ b/internal/rbd/rbd_attach.go @@ -473,7 +473,7 @@ func createPath(ctx context.Context, volOpt *rbdVolume, device string, cr *util. imageOrDeviceSpec: imagePath, isImageSpec: true, isNbd: isNbd, - encrypted: volOpt.isEncrypted(), + encrypted: volOpt.isBlockEncrypted(), volumeID: volOpt.VolID, unmapOptions: volOpt.UnmapOptions, logDir: volOpt.LogDir, diff --git a/internal/rbd/rbd_journal.go b/internal/rbd/rbd_journal.go index eadfa99e7..e0e991464 100644 --- a/internal/rbd/rbd_journal.go +++ b/internal/rbd/rbd_journal.go @@ -246,8 +246,8 @@ func (rv *rbdVolume) Exists(ctx context.Context, parentVol *rbdVolume) (bool, er } kmsID := "" - if rv.isEncrypted() { - kmsID = rv.encryption.GetID() + if rv.isBlockEncrypted() { + kmsID = rv.blockEncryption.GetID() } j, err := volJournal.Connect(rv.Monitors, rv.RadosNamespace, rv.conn.Creds) @@ -387,8 +387,8 @@ func reserveSnap(ctx context.Context, rbdSnap *rbdSnapshot, rbdVol *rbdVolume, c defer j.Destroy() kmsID := "" - if rbdVol.isEncrypted() { - kmsID = rbdVol.encryption.GetID() + if rbdVol.isBlockEncrypted() { + kmsID = rbdVol.blockEncryption.GetID() } rbdSnap.ReservedID, rbdSnap.RbdSnapName, err = j.ReserveName( @@ -461,8 +461,8 @@ func reserveVol(ctx context.Context, rbdVol *rbdVolume, rbdSnap *rbdSnapshot, cr } kmsID := "" - if rbdVol.isEncrypted() { - kmsID = rbdVol.encryption.GetID() + if rbdVol.isBlockEncrypted() { + kmsID = rbdVol.blockEncryption.GetID() } j, err := volJournal.Connect(rbdVol.Monitors, rbdVol.RadosNamespace, cr) diff --git a/internal/rbd/rbd_util.go b/internal/rbd/rbd_util.go index d32c4d391..ff2e682b4 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -118,6 +118,7 @@ type rbdImage struct { ParentPool string // Cluster name ClusterName string + // Owner is the creator (tenant, Kubernetes Namespace) of the volume Owner string @@ -130,9 +131,14 @@ type rbdImage struct { ObjectSize uint64 ImageFeatureSet librbd.FeatureSet - // encryption provides access to optional VolumeEncryption functions - encryption *util.VolumeEncryption + + // blockEncryption provides access to optional VolumeEncryption functions (e.g LUKS) + blockEncryption *util.VolumeEncryption + // fileEncryption provides access to optional VolumeEncryption functions (e.g fscrypt) + fileEncryption *util.VolumeEncryption + CreatedAt *timestamp.Timestamp + // conn is a connection to the Ceph cluster obtained from a ConnPool conn *util.ClusterConnection // an opened IOContext, call .openIoctx() before using @@ -384,8 +390,8 @@ func (ri *rbdImage) Destroy() { if ri.conn != nil { ri.conn.Destroy() } - if ri.isEncrypted() { - ri.encryption.Destroy() + if ri.isBlockEncrypted() { + ri.blockEncryption.Destroy() } } @@ -438,8 +444,8 @@ func createImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) er return fmt.Errorf("failed to create rbd image: %w", err) } - if pOpts.isEncrypted() { - err = pOpts.setupEncryption(ctx) + if pOpts.isBlockEncrypted() { + err = pOpts.setupBlockEncryption(ctx) if err != nil { return fmt.Errorf("failed to setup encryption for image %s: %w", pOpts, err) } @@ -624,9 +630,9 @@ func (ri *rbdImage) deleteImage(ctx context.Context) error { return err } - if ri.isEncrypted() { + if ri.isBlockEncrypted() { log.DebugLog(ctx, "rbd: going to remove DEK for %q", ri) - if err = ri.encryption.RemoveDEK(ri.VolID); err != nil { + if err = ri.blockEncryption.RemoveDEK(ri.VolID); err != nil { log.WarningLog(ctx, "failed to clean the passphrase for volume %s: %s", ri.VolID, err) } } @@ -1009,7 +1015,7 @@ func genSnapFromSnapID( } if imageAttributes.KmsID != "" { - err = rbdSnap.configureEncryption(imageAttributes.KmsID, secrets) + err = rbdSnap.configureBlockEncryption(imageAttributes.KmsID, secrets) if err != nil { return fmt.Errorf("failed to configure encryption for "+ "%q: %w", rbdSnap, err) @@ -1104,7 +1110,7 @@ func generateVolumeFromVolumeID( rbdVol.Owner = imageAttributes.Owner if imageAttributes.KmsID != "" { - err = rbdVol.configureEncryption(imageAttributes.KmsID, secrets) + err = rbdVol.configureBlockEncryption(imageAttributes.KmsID, secrets) if err != nil { return rbdVol, err } @@ -1681,7 +1687,7 @@ func stashRBDImageMetadata(volOptions *rbdVolume, metaDataPath string) error { Pool: volOptions.Pool, RadosNamespace: volOptions.RadosNamespace, ImageName: volOptions.RbdImageName, - Encrypted: volOptions.isEncrypted(), + Encrypted: volOptions.isBlockEncrypted(), UnmapOptions: volOptions.UnmapOptions, } @@ -1962,10 +1968,10 @@ func (ri *rbdImage) getOrigSnapName(snapID uint64) (string, error) { func (ri *rbdImage) isCompatibleEncryption(dst *rbdImage) error { switch { - case ri.isEncrypted() && !dst.isEncrypted(): + case ri.isBlockEncrypted() && !dst.isBlockEncrypted(): return fmt.Errorf("cannot create unencrypted volume from encrypted volume %q", ri) - case !ri.isEncrypted() && dst.isEncrypted(): + case !ri.isBlockEncrypted() && dst.isBlockEncrypted(): return fmt.Errorf("cannot create encrypted volume from unencrypted volume %q", ri) } diff --git a/internal/rbd/snapshot.go b/internal/rbd/snapshot.go index 089946757..c5f0a0bdf 100644 --- a/internal/rbd/snapshot.go +++ b/internal/rbd/snapshot.go @@ -111,7 +111,7 @@ func generateVolFromSnap(rbdSnap *rbdSnapshot) *rbdVolume { // copyEncryptionConfig cannot be used here because the volume and the // snapshot will have the same volumeID which cases the panic in // copyEncryptionConfig function. - vol.encryption = rbdSnap.encryption + vol.blockEncryption = rbdSnap.blockEncryption return vol }