From 6ea73af34c43f77ead6fd3cdbacc2c2de48cc838 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Tue, 4 Mar 2025 08:55:38 +0100 Subject: [PATCH] util: move EncryptionType(s) to pkg/util/crypto Signed-off-by: Niels de Vos --- e2e/rbd.go | 44 +++++++++--------- internal/cephfs/store/fsjournal.go | 8 ++-- internal/cephfs/store/volumeoptions.go | 16 ++++--- internal/journal/voljournal.go | 30 ++++++------ internal/rbd/encryption.go | 28 ++++++------ internal/rbd/encryption_test.go | 22 ++++----- internal/rbd/rbd_journal.go | 14 +++--- internal/rbd/rbd_util.go | 10 ++-- internal/util/crypto.go | 54 ++-------------------- internal/util/crypto_test.go | 30 ++++-------- pkg/util/crypto/types.go | 63 ++++++++++++++++++++++++++ pkg/util/crypto/types_test.go | 38 ++++++++++++++++ 12 files changed, 206 insertions(+), 151 deletions(-) create mode 100644 pkg/util/crypto/types.go create mode 100644 pkg/util/crypto/types_test.go diff --git a/e2e/rbd.go b/e2e/rbd.go index 344d269f6..6f4098f26 100644 --- a/e2e/rbd.go +++ b/e2e/rbd.go @@ -264,10 +264,10 @@ func checkClusternameInMetadata(f *framework.Framework, ns, pool, image string) // ByFileAndBlockEncryption wraps ginkgo's By to run the test body using file and block encryption specific validators. func ByFileAndBlockEncryption( text string, - callback func(validator encryptionValidateFunc, pvcValidator validateFunc, encryptionType util.EncryptionType), + callback func(validator encryptionValidateFunc, pvcValidator validateFunc, encryptionType crypto.EncryptionType), ) { By(text+" (block)", func() { - callback(validateEncryptedPVCAndAppBinding, isBlockEncryptedPVC, util.EncryptionTypeBlock) + callback(validateEncryptedPVCAndAppBinding, isBlockEncryptedPVC, crypto.EncryptionTypeBlock) }) By(text+" (file)", func() { if !testRBDFSCrypt { @@ -275,7 +275,7 @@ func ByFileAndBlockEncryption( return } - callback(validateEncryptedFilesystemAndAppBinding, isFileEncryptedPVC, util.EncryptionTypeFile) + callback(validateEncryptedFilesystemAndAppBinding, isFileEncryptedPVC, crypto.EncryptionTypeFile) }) } @@ -2000,7 +2000,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("create a PVC and bind it to an app using rbd-nbd mounter with encryption", func( - validator encryptionValidateFunc, _ validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, _ validateFunc, encType crypto.EncryptionType, ) { if !testNBD { framework.Logf("skipping NBD test") @@ -2046,7 +2046,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("create a PVC and bind it to an app with encrypted RBD volume", func( - validator encryptionValidateFunc, _ validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, _ validateFunc, encType crypto.EncryptionType, ) { err := deleteResource(rbdExamplePath + "storageclass.yaml") if err != nil { @@ -2080,7 +2080,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("Resize Encrypted Block PVC and check Device size", func( - validator encryptionValidateFunc, _ validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, _ validateFunc, encType crypto.EncryptionType, ) { err := deleteResource(rbdExamplePath + "storageclass.yaml") if err != nil { @@ -2106,7 +2106,7 @@ var _ = Describe("RBD", func() { validateRBDImageCount(f, 0, defaultRBDPool) validateOmapCount(f, 0, rbdType, defaultRBDPool, volumesType) - if encType != util.EncryptionTypeFile { + if encType != crypto.EncryptionTypeFile { // Block PVC resize err = resizePVCAndValidateSize(rawPvcPath, rawAppPath, f) if err != nil { @@ -2127,7 +2127,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("create a PVC and bind it to an app with encrypted RBD volume with VaultKMS", func( - validator encryptionValidateFunc, _ validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, _ validateFunc, encType crypto.EncryptionType, ) { err := deleteResource(rbdExamplePath + "storageclass.yaml") if err != nil { @@ -2160,7 +2160,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("create a PVC and bind it to an app with encrypted RBD volume with VaultTokensKMS", func( - validator encryptionValidateFunc, _ validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, _ validateFunc, encType crypto.EncryptionType, ) { err := deleteResource(rbdExamplePath + "storageclass.yaml") if err != nil { @@ -2214,7 +2214,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("create a PVC and bind it to an app with encrypted RBD volume with VaultTenantSA KMS", func( - validator encryptionValidateFunc, _ validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, _ validateFunc, encType crypto.EncryptionType, ) { err := deleteResource(rbdExamplePath + "storageclass.yaml") if err != nil { @@ -2254,7 +2254,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("create a PVC and bind it to an app with encrypted RBD volume with SecretsMetadataKMS", - func(validator encryptionValidateFunc, _ validateFunc, encType util.EncryptionType) { + func(validator encryptionValidateFunc, _ validateFunc, encType crypto.EncryptionType) { err := deleteResource(rbdExamplePath + "storageclass.yaml") if err != nil { framework.Failf("failed to delete storageclass: %v", err) @@ -2286,7 +2286,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("test RBD volume encryption with user secrets based SecretsMetadataKMS", func( - validator encryptionValidateFunc, _ validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, _ validateFunc, encType crypto.EncryptionType, ) { err := deleteResource(rbdExamplePath + "storageclass.yaml") if err != nil { @@ -2341,7 +2341,7 @@ var _ = Describe("RBD", func() { ByFileAndBlockEncryption( "test RBD volume encryption with user secrets based SecretsMetadataKMS with tenant namespace", - func(validator encryptionValidateFunc, isEncryptedPVC validateFunc, encType util.EncryptionType) { + func(validator encryptionValidateFunc, isEncryptedPVC validateFunc, encType crypto.EncryptionType) { err := deleteResource(rbdExamplePath + "storageclass.yaml") if err != nil { framework.Failf("failed to delete storageclass: %v", err) @@ -2467,7 +2467,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("create an encrypted PVC snapshot and restore it for an app with VaultKMS", func( - validator encryptionValidateFunc, isEncryptedPVC validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, isEncryptedPVC validateFunc, encType crypto.EncryptionType, ) { err := deleteResource(rbdExamplePath + "storageclass.yaml") if err != nil { @@ -2500,7 +2500,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("Validate PVC restore from vaultKMS to vaultTenantSAKMS", func( - validator encryptionValidateFunc, isEncryptedPVC validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, isEncryptedPVC validateFunc, encType crypto.EncryptionType, ) { restoreSCName := "restore-sc" err := deleteResource(rbdExamplePath + "storageclass.yaml") @@ -2560,7 +2560,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("Validate PVC-PVC clone with different SC from vaultKMS to vaultTenantSAKMS", func( - validator encryptionValidateFunc, isValidPVC validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, isValidPVC validateFunc, encType crypto.EncryptionType, ) { restoreSCName := "restore-sc" err := deleteResource(rbdExamplePath + "storageclass.yaml") @@ -2624,7 +2624,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("create an encrypted PVC-PVC clone and bind it to an app", func( - validator encryptionValidateFunc, isValidPVC validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, isValidPVC validateFunc, encType crypto.EncryptionType, ) { err := deleteResource(rbdExamplePath + "storageclass.yaml") if err != nil { @@ -2662,7 +2662,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("create an encrypted PVC-PVC clone and bind it to an app with VaultKMS", func( - validator encryptionValidateFunc, isValidPVC validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, isValidPVC validateFunc, encType crypto.EncryptionType, ) { err := deleteResource(rbdExamplePath + "storageclass.yaml") if err != nil { @@ -4362,7 +4362,7 @@ var _ = Describe("RBD", func() { }) ByFileAndBlockEncryption("restore snapshot to bigger size encrypted PVC with VaultKMS", func( - _ encryptionValidateFunc, _ validateFunc, encType util.EncryptionType, + _ encryptionValidateFunc, _ validateFunc, encType crypto.EncryptionType, ) { scOpts := map[string]string{ "encrypted": "true", @@ -4399,7 +4399,7 @@ var _ = Describe("RBD", func() { if err != nil { framework.Failf("failed to validate restore bigger size clone: %v", err) } - if encType != util.EncryptionTypeFile { + if encType != crypto.EncryptionTypeFile { // validate block mode PVC err = validateBiggerPVCFromSnapshot(f, rawPvcPath, @@ -4425,7 +4425,7 @@ var _ = Describe("RBD", func() { By("clone PVC to a bigger size PVC", func() { ByFileAndBlockEncryption("clone PVC to bigger size encrypted PVC with VaultKMS", func( - validator encryptionValidateFunc, _ validateFunc, encType util.EncryptionType, + validator encryptionValidateFunc, _ validateFunc, encType crypto.EncryptionType, ) { scOpts := map[string]string{ "encrypted": "true", @@ -4452,7 +4452,7 @@ var _ = Describe("RBD", func() { if err != nil { framework.Failf("failed to validate bigger size clone: %v", err) } - if encType != util.EncryptionTypeFile { + if encType != crypto.EncryptionTypeFile { // validate block mode PVC err = validateBiggerCloneFromPVC(f, rawPvcPath, diff --git a/internal/cephfs/store/fsjournal.go b/internal/cephfs/store/fsjournal.go index dc9115ac3..f7cbe779c 100644 --- a/internal/cephfs/store/fsjournal.go +++ b/internal/cephfs/store/fsjournal.go @@ -27,6 +27,8 @@ import ( "github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util/log" + "github.com/ceph/ceph-csi/pkg/util/crypto" + "github.com/golang/protobuf/ptypes/timestamp" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -263,12 +265,12 @@ func updateTopologyConstraints(volOpts *VolumeOptions) error { return nil } -func getEncryptionConfig(volOptions *VolumeOptions) (string, util.EncryptionType) { +func getEncryptionConfig(volOptions *VolumeOptions) (string, crypto.EncryptionType) { if volOptions.IsEncrypted() { - return volOptions.Encryption.GetID(), util.EncryptionTypeFile + return volOptions.Encryption.GetID(), crypto.EncryptionTypeFile } - return "", util.EncryptionTypeNone + return "", crypto.EncryptionTypeNone } // ReserveVol is a helper routine to request a UUID reservation for the CSI VolumeName and, diff --git a/internal/cephfs/store/volumeoptions.go b/internal/cephfs/store/volumeoptions.go index 285b15ffc..220519f17 100644 --- a/internal/cephfs/store/volumeoptions.go +++ b/internal/cephfs/store/volumeoptions.go @@ -26,6 +26,8 @@ import ( "github.com/container-storage-interface/spec/lib/go/csi" + "github.com/ceph/ceph-csi/pkg/util/crypto" + cephcsi "github.com/ceph/ceph-csi/api/deploy/kubernetes" "github.com/ceph/ceph-csi/internal/cephfs/core" cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors" @@ -37,7 +39,7 @@ import ( ) const ( - cephfsDefaultEncryptionType = util.EncryptionTypeFile + cephfsDefaultEncryptionType = crypto.EncryptionTypeFile ) type VolumeOptions struct { @@ -906,7 +908,7 @@ func GenSnapFromOptions(ctx context.Context, req *csi.CreateSnapshotRequest) (*S return cephfsSnap, nil } -func parseEncryptionOpts(volOptions map[string]string) (string, util.EncryptionType, error) { +func parseEncryptionOpts(volOptions map[string]string) (string, crypto.EncryptionType, error) { var ( err error ok bool @@ -914,11 +916,11 @@ func parseEncryptionOpts(volOptions map[string]string) (string, util.EncryptionT ) encrypted, ok = volOptions["encrypted"] if !ok { - return "", util.EncryptionTypeNone, nil + return "", crypto.EncryptionTypeNone, nil } kmsID, err = util.FetchEncryptionKMSID(encrypted, volOptions["encryptionKMSID"]) if err != nil { - return "", util.EncryptionTypeInvalid, err + return "", crypto.EncryptionTypeInvalid, err } encType := util.FetchEncryptionType(volOptions, cephfsDefaultEncryptionType) @@ -933,7 +935,7 @@ func IsEncrypted(ctx context.Context, volOptions map[string]string) (bool, error return false, err } - return encType == util.EncryptionTypeFile, nil + return encType == crypto.EncryptionTypeFile, nil } // CopyEncryptionConfig copies passphrases and initializes a fresh @@ -1022,11 +1024,11 @@ func (vo *VolumeOptions) InitKMS( return err } - if encType == util.EncryptionTypeNone { + if encType == crypto.EncryptionTypeNone { return nil } - if encType != util.EncryptionTypeFile { + if encType != crypto.EncryptionTypeFile { return fmt.Errorf("unsupported encryption type %v. only supported type is 'file'", encType) } diff --git a/internal/journal/voljournal.go b/internal/journal/voljournal.go index d57ece947..c0573005e 100644 --- a/internal/journal/voljournal.go +++ b/internal/journal/voljournal.go @@ -24,6 +24,8 @@ import ( "fmt" "strings" + "github.com/ceph/ceph-csi/pkg/util/crypto" + "github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util/log" @@ -291,7 +293,7 @@ Return values: */ func (conn *Connection) CheckReservation(ctx context.Context, journalPool, reqName, namePrefix, snapParentName, kmsConfig string, - encryptionType util.EncryptionType, + encryptionType crypto.EncryptionType, ) (*ImageData, error) { var ( snapSource bool @@ -389,7 +391,7 @@ func (conn *Connection) CheckReservation(ctx context.Context, } } - if encryptionType != util.EncryptionTypeNone { + if encryptionType != crypto.EncryptionTypeNone { if savedImageAttributes.EncryptionType != encryptionType { return nil, fmt.Errorf("internal state inconsistent, omap encryption type"+ " mismatch, request type %q(%d) volume UUID (%s) volume omap encryption type %q (%d)", @@ -567,7 +569,7 @@ func (conn *Connection) ReserveName(ctx context.Context, imagePool string, imagePoolID int64, reqName, namePrefix, parentName, kmsConf, volUUID, owner, backingSnapshotID string, - encryptionType util.EncryptionType, + encryptionType crypto.EncryptionType, ) (string, string, error) { // TODO: Take in-arg as ImageAttributes? var ( @@ -685,16 +687,16 @@ func (conn *Connection) ReserveName(ctx context.Context, // ImageAttributes contains all CSI stored image attributes, typically as OMap keys. type ImageAttributes struct { - RequestName string // Contains the request name for the passed in UUID - SourceName string // Contains the parent image name for the passed in UUID, if it is a snapshot - ImageName string // Contains the image or subvolume name for the passed in UUID - KmsID string // Contains encryption KMS, if it is an encrypted image - EncryptionType util.EncryptionType // Type of encryption used, if image encrypted - Owner string // Contains the owner to be used in combination with KmsID (for some KMS) - ImageID string // Contains the image id - GroupID string // Contains the group id of the image - JournalPoolID int64 // Pool ID of the CSI journal pool, stored in big endian format (on-disk data) - BackingSnapshotID string // ID of the snapshot on which the CephFS snapshot-backed volume is based + RequestName string // Contains the request name for the passed in UUID + SourceName string // Contains the parent image name for the passed in UUID, if it is a snapshot + ImageName string // Contains the image or subvolume name for the passed in UUID + KmsID string // Contains encryption KMS, if it is an encrypted image + EncryptionType crypto.EncryptionType // Type of encryption used, if image encrypted + Owner string // Contains the owner to be used in combination with KmsID (for some KMS) + ImageID string // Contains the image id + GroupID string // Contains the group id of the image + JournalPoolID int64 // Pool ID of the CSI journal pool, stored in big endian format (on-disk data) + BackingSnapshotID string // ID of the snapshot on which the CephFS snapshot-backed volume is based } // GetImageAttributes fetches all keys and their values, from a UUID directory, returning ImageAttributes structure. @@ -740,7 +742,7 @@ func (conn *Connection) GetImageAttributes( var found bool imageAttributes.RequestName = values[cj.csiNameKey] imageAttributes.KmsID = values[cj.encryptKMSKey] - imageAttributes.EncryptionType = util.ParseEncryptionType(values[cj.encryptionType]) + imageAttributes.EncryptionType = crypto.ParseEncryptionType(values[cj.encryptionType]) imageAttributes.Owner = values[cj.ownerKey] imageAttributes.ImageID = values[cj.csiImageIDKey] imageAttributes.BackingSnapshotID = values[cj.backingSnapshotIDKey] diff --git a/internal/rbd/encryption.go b/internal/rbd/encryption.go index eadef94fb..b931a2af4 100644 --- a/internal/rbd/encryption.go +++ b/internal/rbd/encryption.go @@ -24,6 +24,8 @@ import ( "strings" "time" + "github.com/ceph/ceph-csi/pkg/util/crypto" + kmsapi "github.com/ceph/ceph-csi/internal/kms" "github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util/cryptsetup" @@ -65,7 +67,7 @@ const ( // rbdDefaultEncryptionType is the default to use when the // user did not specify an "encryptionType", but set // "encryption": true. - rbdDefaultEncryptionType = util.EncryptionTypeBlock + rbdDefaultEncryptionType = crypto.EncryptionTypeBlock // Luks slots. luksSlot0 = "0" @@ -111,12 +113,12 @@ func (ri *rbdImage) isFileEncrypted() bool { } func IsFileEncrypted(ctx context.Context, volOptions map[string]string) (bool, error) { - _, encType, err := ParseEncryptionOpts(volOptions, util.EncryptionTypeInvalid) + _, encType, err := ParseEncryptionOpts(volOptions, crypto.EncryptionTypeInvalid) if err != nil { return false, err } - return encType == util.EncryptionTypeFile, nil + return encType == crypto.EncryptionTypeFile, nil } // setupBlockEncryption configures the metadata of the RBD image for encryption: @@ -314,13 +316,13 @@ func (ri *rbdImage) initKMS(ctx context.Context, volOptions, credentials map[str } switch encType { - case util.EncryptionTypeBlock: + case crypto.EncryptionTypeBlock: err = ri.configureBlockEncryption(kmsID, credentials) - case util.EncryptionTypeFile: + case crypto.EncryptionTypeFile: err = ri.configureFileEncryption(ctx, kmsID, credentials) - case util.EncryptionTypeInvalid: + case crypto.EncryptionTypeInvalid: return errors.New("invalid encryption type") - case util.EncryptionTypeNone: + case crypto.EncryptionTypeNone: return nil } @@ -334,8 +336,8 @@ func (ri *rbdImage) initKMS(ctx context.Context, volOptions, credentials map[str // ParseEncryptionOpts returns kmsID and sets Owner attribute. func ParseEncryptionOpts( volOptions map[string]string, - fallbackEncType util.EncryptionType, -) (string, util.EncryptionType, error) { + fallbackEncType crypto.EncryptionType, +) (string, crypto.EncryptionType, error) { var ( err error ok bool @@ -343,18 +345,18 @@ func ParseEncryptionOpts( ) encrypted, ok = volOptions["encrypted"] if !ok { - return "", util.EncryptionTypeNone, nil + return "", crypto.EncryptionTypeNone, nil } ok, err = strconv.ParseBool(encrypted) if err != nil { - return "", util.EncryptionTypeInvalid, err + return "", crypto.EncryptionTypeInvalid, err } if !ok { - return "", util.EncryptionTypeNone, nil + return "", crypto.EncryptionTypeNone, nil } kmsID, err = util.FetchEncryptionKMSID(encrypted, volOptions["encryptionKMSID"]) if err != nil { - return "", util.EncryptionTypeInvalid, err + return "", crypto.EncryptionTypeInvalid, err } encType := util.FetchEncryptionType(volOptions, fallbackEncType) diff --git a/internal/rbd/encryption_test.go b/internal/rbd/encryption_test.go index 731daf714..1e49c9a51 100644 --- a/internal/rbd/encryption_test.go +++ b/internal/rbd/encryption_test.go @@ -19,7 +19,7 @@ package rbd import ( "testing" - "github.com/ceph/ceph-csi/internal/util" + "github.com/ceph/ceph-csi/pkg/util/crypto" ) func TestParseEncryptionOpts(t *testing.T) { @@ -27,9 +27,9 @@ func TestParseEncryptionOpts(t *testing.T) { tests := []struct { testName string volOptions map[string]string - fallbackType util.EncryptionType + fallbackType crypto.EncryptionType expectedKMS string - expectedEnc util.EncryptionType + expectedEnc crypto.EncryptionType expectedErr bool }{ { @@ -37,9 +37,9 @@ func TestParseEncryptionOpts(t *testing.T) { volOptions: map[string]string{ "foo": "bar", }, - fallbackType: util.EncryptionTypeBlock, + fallbackType: crypto.EncryptionTypeBlock, expectedKMS: "", - expectedEnc: util.EncryptionTypeNone, + expectedEnc: crypto.EncryptionTypeNone, expectedErr: false, }, { @@ -47,9 +47,9 @@ func TestParseEncryptionOpts(t *testing.T) { volOptions: map[string]string{ "encrypted": "false", }, - fallbackType: util.EncryptionTypeBlock, + fallbackType: crypto.EncryptionTypeBlock, expectedKMS: "", - expectedEnc: util.EncryptionTypeNone, + expectedEnc: crypto.EncryptionTypeNone, expectedErr: false, }, { @@ -57,9 +57,9 @@ func TestParseEncryptionOpts(t *testing.T) { volOptions: map[string]string{ "encrypted": "notbool", }, - fallbackType: util.EncryptionTypeBlock, + fallbackType: crypto.EncryptionTypeBlock, expectedKMS: "", - expectedEnc: util.EncryptionTypeInvalid, + expectedEnc: crypto.EncryptionTypeInvalid, expectedErr: true, }, { @@ -68,9 +68,9 @@ func TestParseEncryptionOpts(t *testing.T) { "encrypted": "true", "encryptionKMSID": "valid-kms-id", }, - fallbackType: util.EncryptionTypeBlock, + fallbackType: crypto.EncryptionTypeBlock, expectedKMS: "valid-kms-id", - expectedEnc: util.EncryptionTypeBlock, + expectedEnc: crypto.EncryptionTypeBlock, expectedErr: false, }, } diff --git a/internal/rbd/rbd_journal.go b/internal/rbd/rbd_journal.go index 35aee1fe6..0e7901f9b 100644 --- a/internal/rbd/rbd_journal.go +++ b/internal/rbd/rbd_journal.go @@ -21,6 +21,8 @@ import ( "errors" "fmt" + "github.com/ceph/ceph-csi/pkg/util/crypto" + "github.com/ceph/ceph-csi/internal/journal" "github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util/k8s" @@ -91,14 +93,14 @@ func validateRbdVol(rbdVol *rbdVolume) error { return err } -func getEncryptionConfig(rbdVol *rbdVolume) (string, util.EncryptionType) { +func getEncryptionConfig(rbdVol *rbdVolume) (string, crypto.EncryptionType) { switch { case rbdVol.isBlockEncrypted(): - return rbdVol.blockEncryption.GetID(), util.EncryptionTypeBlock + return rbdVol.blockEncryption.GetID(), crypto.EncryptionTypeBlock case rbdVol.isFileEncrypted(): - return rbdVol.fileEncryption.GetID(), util.EncryptionTypeFile + return rbdVol.fileEncryption.GetID(), crypto.EncryptionTypeFile default: - return "", util.EncryptionTypeNone + return "", crypto.EncryptionTypeNone } } @@ -145,7 +147,7 @@ func checkSnapCloneExists( defer j.Destroy() snapData, err := j.CheckReservation(ctx, rbdSnap.JournalPool, - rbdSnap.RequestName, rbdSnap.NamePrefix, rbdSnap.RbdImageName, "", util.EncryptionTypeNone) + rbdSnap.RequestName, rbdSnap.NamePrefix, rbdSnap.RbdImageName, "", crypto.EncryptionTypeNone) if err != nil { return false, err } @@ -585,7 +587,7 @@ func RegenerateJournal( vi util.CSIIdentifier rbdVol *rbdVolume kmsID string - encryptionType util.EncryptionType + encryptionType crypto.EncryptionType err error ok bool ) diff --git a/internal/rbd/rbd_util.go b/internal/rbd/rbd_util.go index 1bb1c1ea4..016499df2 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -28,6 +28,8 @@ import ( "strings" "time" + "github.com/ceph/ceph-csi/pkg/util/crypto" + "github.com/ceph/ceph-csi/internal/rbd/types" "github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util/log" @@ -1078,14 +1080,14 @@ func genSnapFromSnapID( } }() - if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == util.EncryptionTypeBlock { + if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == crypto.EncryptionTypeBlock { err = rbdSnap.configureBlockEncryption(imageAttributes.KmsID, secrets) if err != nil { return rbdSnap, fmt.Errorf("failed to configure block encryption for "+ "%q: %w", rbdSnap, err) } } - if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == util.EncryptionTypeFile { + if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == crypto.EncryptionTypeFile { err = rbdSnap.configureFileEncryption(ctx, imageAttributes.KmsID, secrets) if err != nil { return rbdSnap, fmt.Errorf("failed to configure file encryption for "+ @@ -1180,13 +1182,13 @@ func generateVolumeFromVolumeID( rbdVol.ImageID = imageAttributes.ImageID rbdVol.Owner = imageAttributes.Owner - if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == util.EncryptionTypeBlock { + if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == crypto.EncryptionTypeBlock { err = rbdVol.configureBlockEncryption(imageAttributes.KmsID, secrets) if err != nil { return rbdVol, err } } - if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == util.EncryptionTypeFile { + if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == crypto.EncryptionTypeFile { err = rbdVol.configureFileEncryption(ctx, imageAttributes.KmsID, secrets) if err != nil { return rbdVol, err diff --git a/internal/util/crypto.go b/internal/util/crypto.go index 03ef4aeee..0a12c8ac7 100644 --- a/internal/util/crypto.go +++ b/internal/util/crypto.go @@ -26,6 +26,8 @@ import ( "strconv" "strings" + "github.com/ceph/ceph-csi/pkg/util/crypto" + "github.com/ceph/ceph-csi/internal/kms" "github.com/ceph/ceph-csi/internal/util/cryptsetup" "github.com/ceph/ceph-csi/internal/util/log" @@ -83,66 +85,20 @@ func FetchEncryptionKMSID(encrypted, kmsID string) (string, error) { return kmsID, nil } -type EncryptionType int - -const ( - // EncryptionTypeInvalid signals invalid or unsupported configuration. - EncryptionTypeInvalid EncryptionType = iota - // EncryptionTypeNone disables encryption. - EncryptionTypeNone - // EncryptionTypeBlock enables block encryption. - EncryptionTypeBlock - // EncryptionTypeBlock enables file encryption (fscrypt). - EncryptionTypeFile -) - -const ( - encryptionTypeBlockString = "block" - encryptionTypeFileString = "file" -) - -func ParseEncryptionType(typeStr string) EncryptionType { - switch typeStr { - case encryptionTypeBlockString: - return EncryptionTypeBlock - case encryptionTypeFileString: - return EncryptionTypeFile - case "": - return EncryptionTypeNone - default: - return EncryptionTypeInvalid - } -} - -func (encType EncryptionType) String() string { - switch encType { - case EncryptionTypeBlock: - return encryptionTypeBlockString - case EncryptionTypeFile: - return encryptionTypeFileString - case EncryptionTypeNone: - return "" - case EncryptionTypeInvalid: - return "INVALID" - default: - return "UNKNOWN" - } -} - // FetchEncryptionType returns encryptionType specified in volOptions. // If not specified, use fallback. If specified but invalid, return // invalid. -func FetchEncryptionType(volOptions map[string]string, fallback EncryptionType) EncryptionType { +func FetchEncryptionType(volOptions map[string]string, fallback crypto.EncryptionType) crypto.EncryptionType { encType, ok := volOptions["encryptionType"] if !ok { return fallback } if encType == "" { - return EncryptionTypeInvalid + return crypto.EncryptionTypeInvalid } - return ParseEncryptionType(encType) + return crypto.ParseEncryptionType(encType) } // NewVolumeEncryption creates a new instance of VolumeEncryption and diff --git a/internal/util/crypto_test.go b/internal/util/crypto_test.go index d09f3a283..adf46ac6a 100644 --- a/internal/util/crypto_test.go +++ b/internal/util/crypto_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/ceph/ceph-csi/internal/kms" + "github.com/ceph/ceph-csi/pkg/util/crypto" "github.com/stretchr/testify/require" ) @@ -65,33 +66,18 @@ func TestKMSWorkflow(t *testing.T) { require.Equal(t, secrets["encryptionPassphrase"], passphrase) } -func TestEncryptionType(t *testing.T) { - t.Parallel() - require.EqualValues(t, EncryptionTypeInvalid, ParseEncryptionType("wat?")) - require.EqualValues(t, EncryptionTypeInvalid, ParseEncryptionType("both")) - require.EqualValues(t, EncryptionTypeInvalid, ParseEncryptionType("file,block")) - require.EqualValues(t, EncryptionTypeInvalid, ParseEncryptionType("block,file")) - require.EqualValues(t, EncryptionTypeBlock, ParseEncryptionType("block")) - require.EqualValues(t, EncryptionTypeFile, ParseEncryptionType("file")) - require.EqualValues(t, EncryptionTypeNone, ParseEncryptionType("")) - - for _, s := range []string{"file", "block", ""} { - require.EqualValues(t, s, ParseEncryptionType(s).String()) - } -} - func TestFetchEncryptionType(t *testing.T) { t.Parallel() volOpts := map[string]string{} - require.EqualValues(t, EncryptionTypeBlock, FetchEncryptionType(volOpts, EncryptionTypeBlock)) - require.EqualValues(t, EncryptionTypeFile, FetchEncryptionType(volOpts, EncryptionTypeFile)) - require.EqualValues(t, EncryptionTypeNone, FetchEncryptionType(volOpts, EncryptionTypeNone)) + require.EqualValues(t, crypto.EncryptionTypeBlock, FetchEncryptionType(volOpts, crypto.EncryptionTypeBlock)) + require.EqualValues(t, crypto.EncryptionTypeFile, FetchEncryptionType(volOpts, crypto.EncryptionTypeFile)) + require.EqualValues(t, crypto.EncryptionTypeNone, FetchEncryptionType(volOpts, crypto.EncryptionTypeNone)) volOpts["encryptionType"] = "" - require.EqualValues(t, EncryptionTypeInvalid, FetchEncryptionType(volOpts, EncryptionTypeNone)) + require.EqualValues(t, crypto.EncryptionTypeInvalid, FetchEncryptionType(volOpts, crypto.EncryptionTypeNone)) volOpts["encryptionType"] = "block" - require.EqualValues(t, EncryptionTypeBlock, FetchEncryptionType(volOpts, EncryptionTypeNone)) + require.EqualValues(t, crypto.EncryptionTypeBlock, FetchEncryptionType(volOpts, crypto.EncryptionTypeNone)) volOpts["encryptionType"] = "file" - require.EqualValues(t, EncryptionTypeFile, FetchEncryptionType(volOpts, EncryptionTypeNone)) + require.EqualValues(t, crypto.EncryptionTypeFile, FetchEncryptionType(volOpts, crypto.EncryptionTypeNone)) volOpts["encryptionType"] = "INVALID" - require.EqualValues(t, EncryptionTypeInvalid, FetchEncryptionType(volOpts, EncryptionTypeNone)) + require.EqualValues(t, crypto.EncryptionTypeInvalid, FetchEncryptionType(volOpts, crypto.EncryptionTypeNone)) } diff --git a/pkg/util/crypto/types.go b/pkg/util/crypto/types.go new file mode 100644 index 000000000..bb2709f9b --- /dev/null +++ b/pkg/util/crypto/types.go @@ -0,0 +1,63 @@ +/* +Copyright 2025 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 crypto + +type EncryptionType int + +const ( + // EncryptionTypeInvalid signals invalid or unsupported configuration. + EncryptionTypeInvalid EncryptionType = iota + // EncryptionTypeNone disables encryption. + EncryptionTypeNone + // EncryptionTypeBlock enables block encryption. + EncryptionTypeBlock + // EncryptionTypeBlock enables file encryption (fscrypt). + EncryptionTypeFile +) + +const ( + encryptionTypeBlockString = "block" + encryptionTypeFileString = "file" +) + +func ParseEncryptionType(typeStr string) EncryptionType { + switch typeStr { + case encryptionTypeBlockString: + return EncryptionTypeBlock + case encryptionTypeFileString: + return EncryptionTypeFile + case "": + return EncryptionTypeNone + default: + return EncryptionTypeInvalid + } +} + +func (encType EncryptionType) String() string { + switch encType { + case EncryptionTypeBlock: + return encryptionTypeBlockString + case EncryptionTypeFile: + return encryptionTypeFileString + case EncryptionTypeNone: + return "" + case EncryptionTypeInvalid: + return "INVALID" + default: + return "UNKNOWN" + } +} diff --git a/pkg/util/crypto/types_test.go b/pkg/util/crypto/types_test.go new file mode 100644 index 000000000..0fcf731da --- /dev/null +++ b/pkg/util/crypto/types_test.go @@ -0,0 +1,38 @@ +/* +Copyright 2025 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 crypto + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestEncryptionType(t *testing.T) { + t.Parallel() + require.EqualValues(t, EncryptionTypeInvalid, ParseEncryptionType("wat?")) + require.EqualValues(t, EncryptionTypeInvalid, ParseEncryptionType("both")) + require.EqualValues(t, EncryptionTypeInvalid, ParseEncryptionType("file,block")) + require.EqualValues(t, EncryptionTypeInvalid, ParseEncryptionType("block,file")) + require.EqualValues(t, EncryptionTypeBlock, ParseEncryptionType("block")) + require.EqualValues(t, EncryptionTypeFile, ParseEncryptionType("file")) + require.EqualValues(t, EncryptionTypeNone, ParseEncryptionType("")) + + for _, s := range []string{"file", "block", ""} { + require.EqualValues(t, s, ParseEncryptionType(s).String()) + } +}