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 <marcel.lauhoff@suse.com>
This commit is contained in:
Marcel Lauhoff 2022-05-27 20:03:32 +02:00 committed by mergify[bot]
parent 624905d60d
commit ce9fbb3474
7 changed files with 62 additions and 51 deletions

View File

@ -1560,7 +1560,7 @@ func (cs *ControllerServer) ControllerExpandVolume(
// 2. Block VolumeMode with Encryption // 2. Block VolumeMode with Encryption
// Hence set nodeExpansion flag based on VolumeMode and Encryption status // Hence set nodeExpansion flag based on VolumeMode and Encryption status
nodeExpansion := true nodeExpansion := true
if req.GetVolumeCapability().GetBlock() != nil && !rbdVol.isEncrypted() { if req.GetVolumeCapability().GetBlock() != nil && !rbdVol.isBlockEncrypted() {
nodeExpansion = false nodeExpansion = false
} }

View File

@ -93,16 +93,21 @@ func (ri *rbdImage) ensureEncryptionMetadataSet(status rbdEncryptionState) error
return nil return nil
} }
// isEncrypted returns `true` if the rbdImage is (or needs to be) encrypted. // isBlockEncrypted returns `true` if the rbdImage is (or needs to be) encrypted.
func (ri *rbdImage) isEncrypted() bool { func (ri *rbdImage) isBlockEncrypted() bool {
return ri.encryption != nil 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 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. // - the RBD image will be marked to support encryption in its metadata.
func (ri *rbdImage) setupEncryption(ctx context.Context) error { func (ri *rbdImage) setupBlockEncryption(ctx context.Context) error {
err := ri.encryption.StoreNewCryptoPassphrase(ri.VolID, encryptionPassphraseSize) err := ri.blockEncryption.StoreNewCryptoPassphrase(ri.VolID, encryptionPassphraseSize)
if err != nil { if err != nil {
log.ErrorLog(ctx, "failed to save encryption passphrase for "+ log.ErrorLog(ctx, "failed to save encryption passphrase for "+
"image %s: %s", ri, err) "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). // (Usecase: Restoring snapshot into a storageclass with different encryption config).
func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool) error { func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool) error {
// nothing to do if parent image is not encrypted. // nothing to do if parent image is not encrypted.
if !ri.isEncrypted() { if !ri.isBlockEncrypted() {
return nil return nil
} }
@ -142,21 +147,21 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool)
} }
// get the unencrypted passphrase // get the unencrypted passphrase
passphrase, err := ri.encryption.GetCryptoPassphrase(ri.VolID) passphrase, err := ri.blockEncryption.GetCryptoPassphrase(ri.VolID)
if err != nil { if err != nil {
return fmt.Errorf("failed to fetch passphrase for %q: %w", return fmt.Errorf("failed to fetch passphrase for %q: %w",
ri, err) ri, err)
} }
if !copyOnlyPassphrase { 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) { if errors.Is(err, util.ErrDEKStoreNeeded) {
cp.encryption.SetDEKStore(cp) cp.blockEncryption.SetDEKStore(cp)
} }
} }
// re-encrypt the plain passphrase for the cloned volume // 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 { if err != nil {
return fmt.Errorf("failed to store passphrase for %q: %w", return fmt.Errorf("failed to store passphrase for %q: %w",
cp, err) cp, err)
@ -180,12 +185,12 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool)
// repairEncryptionConfig checks the encryption state of the current rbdImage, // repairEncryptionConfig checks the encryption state of the current rbdImage,
// and makes sure that the destination rbdImage has the same configuration. // and makes sure that the destination rbdImage has the same configuration.
func (ri *rbdImage) repairEncryptionConfig(dest *rbdImage) error { func (ri *rbdImage) repairEncryptionConfig(dest *rbdImage) error {
if !ri.isEncrypted() { if !ri.isBlockEncrypted() {
return nil return nil
} }
// if ri is encrypted, copy its configuration in case it is missing // 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 // dest needs to be connected to the cluster, otherwise it will
// not be possible to write any metadata // not be possible to write any metadata
if dest.conn == nil { 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 { 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 { if err != nil {
log.ErrorLog(ctx, "failed to get crypto passphrase for %s: %v", log.ErrorLog(ctx, "failed to get crypto passphrase for %s: %v",
ri, err) 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) { 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 { if err != nil {
log.ErrorLog(ctx, "failed to get passphrase for encrypted device %s: %v", log.ErrorLog(ctx, "failed to get passphrase for encrypted device %s: %v",
rv, err) rv, err)
@ -264,7 +269,7 @@ func (ri *rbdImage) initKMS(ctx context.Context, volOptions, credentials map[str
return nil return nil
} }
err = ri.configureEncryption(kmsID, credentials) err = ri.configureBlockDeviceEncryption(kmsID, credentials)
if err != nil { if err != nil {
return fmt.Errorf("invalid encryption kms configuration: %w", err) return fmt.Errorf("invalid encryption kms configuration: %w", err)
} }
@ -294,20 +299,20 @@ func (ri *rbdImage) ParseEncryptionOpts(
return kmsID, nil return kmsID, nil
} }
// configureEncryption sets up the VolumeEncryption for this rbdImage. Once // configureBlockDeviceEncryption sets up the VolumeEncryption for this rbdImage. Once
// configured, use isEncrypted() to see if the volume supports encryption. // configured, use isBlockEncrypted() to see if the volume supports block encryption.
func (ri *rbdImage) configureEncryption(kmsID string, credentials map[string]string) error { func (ri *rbdImage) configureBlockEncryption(kmsID string, credentials map[string]string) error {
kms, err := kmsapi.GetKMS(ri.Owner, kmsID, credentials) kms, err := kmsapi.GetKMS(ri.Owner, kmsID, credentials)
if err != nil { if err != nil {
return err 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 // if the KMS can not store the DEK itself, we'll store it in the
// metadata of the RBD image itself // metadata of the RBD image itself
if errors.Is(err, util.ErrDEKStoreNeeded) { if errors.Is(err, util.ErrDEKStoreNeeded) {
ri.encryption.SetDEKStore(ri) ri.blockEncryption.SetDEKStore(ri)
} }
return nil return nil

View File

@ -55,8 +55,8 @@ type stageTransaction struct {
isStagePathCreated bool isStagePathCreated bool
// isMounted represents if the volume was mounted or not // isMounted represents if the volume was mounted or not
isMounted bool isMounted bool
// isEncrypted represents if the volume was encrypted or not // isBlockEncrypted represents if the volume was encrypted or not
isEncrypted bool isBlockEncrypted bool
// devicePath represents the path where rbd device is mapped // devicePath represents the path where rbd device is mapped
devicePath string devicePath string
} }
@ -425,12 +425,12 @@ func (ns *NodeServer) stageTransaction(
} }
} }
if volOptions.isEncrypted() { if volOptions.isBlockEncrypted() {
devicePath, err = ns.processEncryptedDevice(ctx, volOptions, devicePath) devicePath, err = ns.processEncryptedDevice(ctx, volOptions, devicePath)
if err != nil { if err != nil {
return transaction, err return transaction, err
} }
transaction.isEncrypted = true transaction.isBlockEncrypted = true
} }
stagingTargetPath := getStagingTargetPath(req) stagingTargetPath := getStagingTargetPath(req)
@ -475,13 +475,13 @@ func resizeNodeStagePath(ctx context.Context,
var ok bool var ok bool
// if its a non encrypted block device we dont need any expansion // if its a non encrypted block device we dont need any expansion
if isBlock && !transaction.isEncrypted { if isBlock && !transaction.isBlockEncrypted {
return nil return nil
} }
resizer := mount.NewResizeFs(utilexec.New()) resizer := mount.NewResizeFs(utilexec.New())
if transaction.isEncrypted { if transaction.isBlockEncrypted {
devicePath, err = resizeEncryptedDevice(ctx, volID, stagingTargetPath, devicePath) devicePath, err = resizeEncryptedDevice(ctx, volID, stagingTargetPath, devicePath)
if err != nil { if err != nil {
return status.Error(codes.Internal, err.Error()) return status.Error(codes.Internal, err.Error())
@ -611,7 +611,7 @@ func (ns *NodeServer) undoStagingTransaction(
// Unmapping rbd device // Unmapping rbd device
if transaction.devicePath != "" { 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 { if err != nil {
log.ErrorLog( log.ErrorLog(
ctx, ctx,
@ -1146,7 +1146,7 @@ func (ns *NodeServer) processEncryptedDevice(
// CreateVolume. // CreateVolume.
// Use the same setupEncryption() as CreateVolume does, and // Use the same setupEncryption() as CreateVolume does, and
// continue with the common process to crypt-format the device. // continue with the common process to crypt-format the device.
err = volOptions.setupEncryption(ctx) err = volOptions.setupBlockEncryption(ctx)
if err != nil { if err != nil {
log.ErrorLog(ctx, "failed to setup encryption for rbd"+ log.ErrorLog(ctx, "failed to setup encryption for rbd"+
"image %s: %v", imageSpec, err) "image %s: %v", imageSpec, err)

View File

@ -473,7 +473,7 @@ func createPath(ctx context.Context, volOpt *rbdVolume, device string, cr *util.
imageOrDeviceSpec: imagePath, imageOrDeviceSpec: imagePath,
isImageSpec: true, isImageSpec: true,
isNbd: isNbd, isNbd: isNbd,
encrypted: volOpt.isEncrypted(), encrypted: volOpt.isBlockEncrypted(),
volumeID: volOpt.VolID, volumeID: volOpt.VolID,
unmapOptions: volOpt.UnmapOptions, unmapOptions: volOpt.UnmapOptions,
logDir: volOpt.LogDir, logDir: volOpt.LogDir,

View File

@ -246,8 +246,8 @@ func (rv *rbdVolume) Exists(ctx context.Context, parentVol *rbdVolume) (bool, er
} }
kmsID := "" kmsID := ""
if rv.isEncrypted() { if rv.isBlockEncrypted() {
kmsID = rv.encryption.GetID() kmsID = rv.blockEncryption.GetID()
} }
j, err := volJournal.Connect(rv.Monitors, rv.RadosNamespace, rv.conn.Creds) 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() defer j.Destroy()
kmsID := "" kmsID := ""
if rbdVol.isEncrypted() { if rbdVol.isBlockEncrypted() {
kmsID = rbdVol.encryption.GetID() kmsID = rbdVol.blockEncryption.GetID()
} }
rbdSnap.ReservedID, rbdSnap.RbdSnapName, err = j.ReserveName( rbdSnap.ReservedID, rbdSnap.RbdSnapName, err = j.ReserveName(
@ -461,8 +461,8 @@ func reserveVol(ctx context.Context, rbdVol *rbdVolume, rbdSnap *rbdSnapshot, cr
} }
kmsID := "" kmsID := ""
if rbdVol.isEncrypted() { if rbdVol.isBlockEncrypted() {
kmsID = rbdVol.encryption.GetID() kmsID = rbdVol.blockEncryption.GetID()
} }
j, err := volJournal.Connect(rbdVol.Monitors, rbdVol.RadosNamespace, cr) j, err := volJournal.Connect(rbdVol.Monitors, rbdVol.RadosNamespace, cr)

View File

@ -118,6 +118,7 @@ type rbdImage struct {
ParentPool string ParentPool string
// Cluster name // Cluster name
ClusterName string ClusterName string
// Owner is the creator (tenant, Kubernetes Namespace) of the volume // Owner is the creator (tenant, Kubernetes Namespace) of the volume
Owner string Owner string
@ -130,9 +131,14 @@ type rbdImage struct {
ObjectSize uint64 ObjectSize uint64
ImageFeatureSet librbd.FeatureSet 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 CreatedAt *timestamp.Timestamp
// conn is a connection to the Ceph cluster obtained from a ConnPool // conn is a connection to the Ceph cluster obtained from a ConnPool
conn *util.ClusterConnection conn *util.ClusterConnection
// an opened IOContext, call .openIoctx() before using // an opened IOContext, call .openIoctx() before using
@ -384,8 +390,8 @@ func (ri *rbdImage) Destroy() {
if ri.conn != nil { if ri.conn != nil {
ri.conn.Destroy() ri.conn.Destroy()
} }
if ri.isEncrypted() { if ri.isBlockEncrypted() {
ri.encryption.Destroy() 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) return fmt.Errorf("failed to create rbd image: %w", err)
} }
if pOpts.isEncrypted() { if pOpts.isBlockEncrypted() {
err = pOpts.setupEncryption(ctx) err = pOpts.setupBlockEncryption(ctx)
if err != nil { if err != nil {
return fmt.Errorf("failed to setup encryption for image %s: %w", pOpts, err) 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 return err
} }
if ri.isEncrypted() { if ri.isBlockEncrypted() {
log.DebugLog(ctx, "rbd: going to remove DEK for %q", ri) 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) log.WarningLog(ctx, "failed to clean the passphrase for volume %s: %s", ri.VolID, err)
} }
} }
@ -1009,7 +1015,7 @@ func genSnapFromSnapID(
} }
if imageAttributes.KmsID != "" { if imageAttributes.KmsID != "" {
err = rbdSnap.configureEncryption(imageAttributes.KmsID, secrets) err = rbdSnap.configureBlockEncryption(imageAttributes.KmsID, secrets)
if err != nil { if err != nil {
return fmt.Errorf("failed to configure encryption for "+ return fmt.Errorf("failed to configure encryption for "+
"%q: %w", rbdSnap, err) "%q: %w", rbdSnap, err)
@ -1104,7 +1110,7 @@ func generateVolumeFromVolumeID(
rbdVol.Owner = imageAttributes.Owner rbdVol.Owner = imageAttributes.Owner
if imageAttributes.KmsID != "" { if imageAttributes.KmsID != "" {
err = rbdVol.configureEncryption(imageAttributes.KmsID, secrets) err = rbdVol.configureBlockEncryption(imageAttributes.KmsID, secrets)
if err != nil { if err != nil {
return rbdVol, err return rbdVol, err
} }
@ -1681,7 +1687,7 @@ func stashRBDImageMetadata(volOptions *rbdVolume, metaDataPath string) error {
Pool: volOptions.Pool, Pool: volOptions.Pool,
RadosNamespace: volOptions.RadosNamespace, RadosNamespace: volOptions.RadosNamespace,
ImageName: volOptions.RbdImageName, ImageName: volOptions.RbdImageName,
Encrypted: volOptions.isEncrypted(), Encrypted: volOptions.isBlockEncrypted(),
UnmapOptions: volOptions.UnmapOptions, UnmapOptions: volOptions.UnmapOptions,
} }
@ -1962,10 +1968,10 @@ func (ri *rbdImage) getOrigSnapName(snapID uint64) (string, error) {
func (ri *rbdImage) isCompatibleEncryption(dst *rbdImage) error { func (ri *rbdImage) isCompatibleEncryption(dst *rbdImage) error {
switch { switch {
case ri.isEncrypted() && !dst.isEncrypted(): case ri.isBlockEncrypted() && !dst.isBlockEncrypted():
return fmt.Errorf("cannot create unencrypted volume from encrypted volume %q", ri) 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) return fmt.Errorf("cannot create encrypted volume from unencrypted volume %q", ri)
} }

View File

@ -111,7 +111,7 @@ func generateVolFromSnap(rbdSnap *rbdSnapshot) *rbdVolume {
// copyEncryptionConfig cannot be used here because the volume and the // copyEncryptionConfig cannot be used here because the volume and the
// snapshot will have the same volumeID which cases the panic in // snapshot will have the same volumeID which cases the panic in
// copyEncryptionConfig function. // copyEncryptionConfig function.
vol.encryption = rbdSnap.encryption vol.blockEncryption = rbdSnap.blockEncryption
return vol return vol
} }