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 }