util: move EncryptionType(s) to pkg/util/crypto

Signed-off-by: Niels de Vos <ndevos@ibm.com>
This commit is contained in:
Niels de Vos 2025-03-04 08:55:38 +01:00
parent 2e24cbf082
commit 6ea73af34c
12 changed files with 206 additions and 151 deletions

View File

@ -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. // ByFileAndBlockEncryption wraps ginkgo's By to run the test body using file and block encryption specific validators.
func ByFileAndBlockEncryption( func ByFileAndBlockEncryption(
text string, text string,
callback func(validator encryptionValidateFunc, pvcValidator validateFunc, encryptionType util.EncryptionType), callback func(validator encryptionValidateFunc, pvcValidator validateFunc, encryptionType crypto.EncryptionType),
) { ) {
By(text+" (block)", func() { By(text+" (block)", func() {
callback(validateEncryptedPVCAndAppBinding, isBlockEncryptedPVC, util.EncryptionTypeBlock) callback(validateEncryptedPVCAndAppBinding, isBlockEncryptedPVC, crypto.EncryptionTypeBlock)
}) })
By(text+" (file)", func() { By(text+" (file)", func() {
if !testRBDFSCrypt { if !testRBDFSCrypt {
@ -275,7 +275,7 @@ func ByFileAndBlockEncryption(
return 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( 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 { if !testNBD {
framework.Logf("skipping NBD test") 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( 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") err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil { if err != nil {
@ -2080,7 +2080,7 @@ var _ = Describe("RBD", func() {
}) })
ByFileAndBlockEncryption("Resize Encrypted Block PVC and check Device size", 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") err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil { if err != nil {
@ -2106,7 +2106,7 @@ var _ = Describe("RBD", func() {
validateRBDImageCount(f, 0, defaultRBDPool) validateRBDImageCount(f, 0, defaultRBDPool)
validateOmapCount(f, 0, rbdType, defaultRBDPool, volumesType) validateOmapCount(f, 0, rbdType, defaultRBDPool, volumesType)
if encType != util.EncryptionTypeFile { if encType != crypto.EncryptionTypeFile {
// Block PVC resize // Block PVC resize
err = resizePVCAndValidateSize(rawPvcPath, rawAppPath, f) err = resizePVCAndValidateSize(rawPvcPath, rawAppPath, f)
if err != nil { 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( 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") err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil { 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( 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") err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil { 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( 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") err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil { 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", 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") err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil { if err != nil {
framework.Failf("failed to delete storageclass: %v", err) 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( 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") err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil { if err != nil {
@ -2341,7 +2341,7 @@ var _ = Describe("RBD", func() {
ByFileAndBlockEncryption( ByFileAndBlockEncryption(
"test RBD volume encryption with user secrets based SecretsMetadataKMS with tenant namespace", "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") err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil { if err != nil {
framework.Failf("failed to delete storageclass: %v", err) 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( 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") err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil { if err != nil {
@ -2500,7 +2500,7 @@ var _ = Describe("RBD", func() {
}) })
ByFileAndBlockEncryption("Validate PVC restore from vaultKMS to vaultTenantSAKMS", 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" restoreSCName := "restore-sc"
err := deleteResource(rbdExamplePath + "storageclass.yaml") 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( 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" restoreSCName := "restore-sc"
err := deleteResource(rbdExamplePath + "storageclass.yaml") 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( 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") err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil { 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( 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") err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil { if err != nil {
@ -4362,7 +4362,7 @@ var _ = Describe("RBD", func() {
}) })
ByFileAndBlockEncryption("restore snapshot to bigger size encrypted PVC with VaultKMS", 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{ scOpts := map[string]string{
"encrypted": "true", "encrypted": "true",
@ -4399,7 +4399,7 @@ var _ = Describe("RBD", func() {
if err != nil { if err != nil {
framework.Failf("failed to validate restore bigger size clone: %v", err) framework.Failf("failed to validate restore bigger size clone: %v", err)
} }
if encType != util.EncryptionTypeFile { if encType != crypto.EncryptionTypeFile {
// validate block mode PVC // validate block mode PVC
err = validateBiggerPVCFromSnapshot(f, err = validateBiggerPVCFromSnapshot(f,
rawPvcPath, rawPvcPath,
@ -4425,7 +4425,7 @@ var _ = Describe("RBD", func() {
By("clone PVC to a bigger size PVC", func() { By("clone PVC to a bigger size PVC", func() {
ByFileAndBlockEncryption("clone PVC to bigger size encrypted PVC with VaultKMS", 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{ scOpts := map[string]string{
"encrypted": "true", "encrypted": "true",
@ -4452,7 +4452,7 @@ var _ = Describe("RBD", func() {
if err != nil { if err != nil {
framework.Failf("failed to validate bigger size clone: %v", err) framework.Failf("failed to validate bigger size clone: %v", err)
} }
if encType != util.EncryptionTypeFile { if encType != crypto.EncryptionTypeFile {
// validate block mode PVC // validate block mode PVC
err = validateBiggerCloneFromPVC(f, err = validateBiggerCloneFromPVC(f,
rawPvcPath, rawPvcPath,

View File

@ -27,6 +27,8 @@ import (
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/log" "github.com/ceph/ceph-csi/internal/util/log"
"github.com/ceph/ceph-csi/pkg/util/crypto"
"github.com/golang/protobuf/ptypes/timestamp" "github.com/golang/protobuf/ptypes/timestamp"
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
) )
@ -263,12 +265,12 @@ func updateTopologyConstraints(volOpts *VolumeOptions) error {
return nil return nil
} }
func getEncryptionConfig(volOptions *VolumeOptions) (string, util.EncryptionType) { func getEncryptionConfig(volOptions *VolumeOptions) (string, crypto.EncryptionType) {
if volOptions.IsEncrypted() { 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, // ReserveVol is a helper routine to request a UUID reservation for the CSI VolumeName and,

View File

@ -26,6 +26,8 @@ import (
"github.com/container-storage-interface/spec/lib/go/csi" "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" cephcsi "github.com/ceph/ceph-csi/api/deploy/kubernetes"
"github.com/ceph/ceph-csi/internal/cephfs/core" "github.com/ceph/ceph-csi/internal/cephfs/core"
cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors" cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors"
@ -37,7 +39,7 @@ import (
) )
const ( const (
cephfsDefaultEncryptionType = util.EncryptionTypeFile cephfsDefaultEncryptionType = crypto.EncryptionTypeFile
) )
type VolumeOptions struct { type VolumeOptions struct {
@ -906,7 +908,7 @@ func GenSnapFromOptions(ctx context.Context, req *csi.CreateSnapshotRequest) (*S
return cephfsSnap, nil return cephfsSnap, nil
} }
func parseEncryptionOpts(volOptions map[string]string) (string, util.EncryptionType, error) { func parseEncryptionOpts(volOptions map[string]string) (string, crypto.EncryptionType, error) {
var ( var (
err error err error
ok bool ok bool
@ -914,11 +916,11 @@ func parseEncryptionOpts(volOptions map[string]string) (string, util.EncryptionT
) )
encrypted, ok = volOptions["encrypted"] encrypted, ok = volOptions["encrypted"]
if !ok { if !ok {
return "", util.EncryptionTypeNone, nil return "", crypto.EncryptionTypeNone, nil
} }
kmsID, err = util.FetchEncryptionKMSID(encrypted, volOptions["encryptionKMSID"]) kmsID, err = util.FetchEncryptionKMSID(encrypted, volOptions["encryptionKMSID"])
if err != nil { if err != nil {
return "", util.EncryptionTypeInvalid, err return "", crypto.EncryptionTypeInvalid, err
} }
encType := util.FetchEncryptionType(volOptions, cephfsDefaultEncryptionType) encType := util.FetchEncryptionType(volOptions, cephfsDefaultEncryptionType)
@ -933,7 +935,7 @@ func IsEncrypted(ctx context.Context, volOptions map[string]string) (bool, error
return false, err return false, err
} }
return encType == util.EncryptionTypeFile, nil return encType == crypto.EncryptionTypeFile, nil
} }
// CopyEncryptionConfig copies passphrases and initializes a fresh // CopyEncryptionConfig copies passphrases and initializes a fresh
@ -1022,11 +1024,11 @@ func (vo *VolumeOptions) InitKMS(
return err return err
} }
if encType == util.EncryptionTypeNone { if encType == crypto.EncryptionTypeNone {
return nil return nil
} }
if encType != util.EncryptionTypeFile { if encType != crypto.EncryptionTypeFile {
return fmt.Errorf("unsupported encryption type %v. only supported type is 'file'", encType) return fmt.Errorf("unsupported encryption type %v. only supported type is 'file'", encType)
} }

View File

@ -24,6 +24,8 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/ceph/ceph-csi/pkg/util/crypto"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/log" "github.com/ceph/ceph-csi/internal/util/log"
@ -291,7 +293,7 @@ Return values:
*/ */
func (conn *Connection) CheckReservation(ctx context.Context, func (conn *Connection) CheckReservation(ctx context.Context,
journalPool, reqName, namePrefix, snapParentName, kmsConfig string, journalPool, reqName, namePrefix, snapParentName, kmsConfig string,
encryptionType util.EncryptionType, encryptionType crypto.EncryptionType,
) (*ImageData, error) { ) (*ImageData, error) {
var ( var (
snapSource bool 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 { if savedImageAttributes.EncryptionType != encryptionType {
return nil, fmt.Errorf("internal state inconsistent, omap encryption type"+ return nil, fmt.Errorf("internal state inconsistent, omap encryption type"+
" mismatch, request type %q(%d) volume UUID (%s) volume omap encryption type %q (%d)", " 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, imagePool string, imagePoolID int64,
reqName, namePrefix, parentName, kmsConf, volUUID, owner, reqName, namePrefix, parentName, kmsConf, volUUID, owner,
backingSnapshotID string, backingSnapshotID string,
encryptionType util.EncryptionType, encryptionType crypto.EncryptionType,
) (string, string, error) { ) (string, string, error) {
// TODO: Take in-arg as ImageAttributes? // TODO: Take in-arg as ImageAttributes?
var ( var (
@ -685,16 +687,16 @@ func (conn *Connection) ReserveName(ctx context.Context,
// ImageAttributes contains all CSI stored image attributes, typically as OMap keys. // ImageAttributes contains all CSI stored image attributes, typically as OMap keys.
type ImageAttributes struct { type ImageAttributes struct {
RequestName string // Contains the request name for the passed in UUID 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 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 ImageName string // Contains the image or subvolume name for the passed in UUID
KmsID string // Contains encryption KMS, if it is an encrypted image KmsID string // Contains encryption KMS, if it is an encrypted image
EncryptionType util.EncryptionType // Type of encryption used, if image encrypted 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) Owner string // Contains the owner to be used in combination with KmsID (for some KMS)
ImageID string // Contains the image id ImageID string // Contains the image id
GroupID string // Contains the group id of the image 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) 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 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. // 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 var found bool
imageAttributes.RequestName = values[cj.csiNameKey] imageAttributes.RequestName = values[cj.csiNameKey]
imageAttributes.KmsID = values[cj.encryptKMSKey] 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.Owner = values[cj.ownerKey]
imageAttributes.ImageID = values[cj.csiImageIDKey] imageAttributes.ImageID = values[cj.csiImageIDKey]
imageAttributes.BackingSnapshotID = values[cj.backingSnapshotIDKey] imageAttributes.BackingSnapshotID = values[cj.backingSnapshotIDKey]

View File

@ -24,6 +24,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/ceph/ceph-csi/pkg/util/crypto"
kmsapi "github.com/ceph/ceph-csi/internal/kms" kmsapi "github.com/ceph/ceph-csi/internal/kms"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/cryptsetup" "github.com/ceph/ceph-csi/internal/util/cryptsetup"
@ -65,7 +67,7 @@ const (
// rbdDefaultEncryptionType is the default to use when the // rbdDefaultEncryptionType is the default to use when the
// user did not specify an "encryptionType", but set // user did not specify an "encryptionType", but set
// "encryption": true. // "encryption": true.
rbdDefaultEncryptionType = util.EncryptionTypeBlock rbdDefaultEncryptionType = crypto.EncryptionTypeBlock
// Luks slots. // Luks slots.
luksSlot0 = "0" luksSlot0 = "0"
@ -111,12 +113,12 @@ func (ri *rbdImage) isFileEncrypted() bool {
} }
func IsFileEncrypted(ctx context.Context, volOptions map[string]string) (bool, error) { 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 { if err != nil {
return false, err return false, err
} }
return encType == util.EncryptionTypeFile, nil return encType == crypto.EncryptionTypeFile, nil
} }
// setupBlockEncryption configures the metadata of the RBD image for encryption: // 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 { switch encType {
case util.EncryptionTypeBlock: case crypto.EncryptionTypeBlock:
err = ri.configureBlockEncryption(kmsID, credentials) err = ri.configureBlockEncryption(kmsID, credentials)
case util.EncryptionTypeFile: case crypto.EncryptionTypeFile:
err = ri.configureFileEncryption(ctx, kmsID, credentials) err = ri.configureFileEncryption(ctx, kmsID, credentials)
case util.EncryptionTypeInvalid: case crypto.EncryptionTypeInvalid:
return errors.New("invalid encryption type") return errors.New("invalid encryption type")
case util.EncryptionTypeNone: case crypto.EncryptionTypeNone:
return nil return nil
} }
@ -334,8 +336,8 @@ func (ri *rbdImage) initKMS(ctx context.Context, volOptions, credentials map[str
// ParseEncryptionOpts returns kmsID and sets Owner attribute. // ParseEncryptionOpts returns kmsID and sets Owner attribute.
func ParseEncryptionOpts( func ParseEncryptionOpts(
volOptions map[string]string, volOptions map[string]string,
fallbackEncType util.EncryptionType, fallbackEncType crypto.EncryptionType,
) (string, util.EncryptionType, error) { ) (string, crypto.EncryptionType, error) {
var ( var (
err error err error
ok bool ok bool
@ -343,18 +345,18 @@ func ParseEncryptionOpts(
) )
encrypted, ok = volOptions["encrypted"] encrypted, ok = volOptions["encrypted"]
if !ok { if !ok {
return "", util.EncryptionTypeNone, nil return "", crypto.EncryptionTypeNone, nil
} }
ok, err = strconv.ParseBool(encrypted) ok, err = strconv.ParseBool(encrypted)
if err != nil { if err != nil {
return "", util.EncryptionTypeInvalid, err return "", crypto.EncryptionTypeInvalid, err
} }
if !ok { if !ok {
return "", util.EncryptionTypeNone, nil return "", crypto.EncryptionTypeNone, nil
} }
kmsID, err = util.FetchEncryptionKMSID(encrypted, volOptions["encryptionKMSID"]) kmsID, err = util.FetchEncryptionKMSID(encrypted, volOptions["encryptionKMSID"])
if err != nil { if err != nil {
return "", util.EncryptionTypeInvalid, err return "", crypto.EncryptionTypeInvalid, err
} }
encType := util.FetchEncryptionType(volOptions, fallbackEncType) encType := util.FetchEncryptionType(volOptions, fallbackEncType)

View File

@ -19,7 +19,7 @@ package rbd
import ( import (
"testing" "testing"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/pkg/util/crypto"
) )
func TestParseEncryptionOpts(t *testing.T) { func TestParseEncryptionOpts(t *testing.T) {
@ -27,9 +27,9 @@ func TestParseEncryptionOpts(t *testing.T) {
tests := []struct { tests := []struct {
testName string testName string
volOptions map[string]string volOptions map[string]string
fallbackType util.EncryptionType fallbackType crypto.EncryptionType
expectedKMS string expectedKMS string
expectedEnc util.EncryptionType expectedEnc crypto.EncryptionType
expectedErr bool expectedErr bool
}{ }{
{ {
@ -37,9 +37,9 @@ func TestParseEncryptionOpts(t *testing.T) {
volOptions: map[string]string{ volOptions: map[string]string{
"foo": "bar", "foo": "bar",
}, },
fallbackType: util.EncryptionTypeBlock, fallbackType: crypto.EncryptionTypeBlock,
expectedKMS: "", expectedKMS: "",
expectedEnc: util.EncryptionTypeNone, expectedEnc: crypto.EncryptionTypeNone,
expectedErr: false, expectedErr: false,
}, },
{ {
@ -47,9 +47,9 @@ func TestParseEncryptionOpts(t *testing.T) {
volOptions: map[string]string{ volOptions: map[string]string{
"encrypted": "false", "encrypted": "false",
}, },
fallbackType: util.EncryptionTypeBlock, fallbackType: crypto.EncryptionTypeBlock,
expectedKMS: "", expectedKMS: "",
expectedEnc: util.EncryptionTypeNone, expectedEnc: crypto.EncryptionTypeNone,
expectedErr: false, expectedErr: false,
}, },
{ {
@ -57,9 +57,9 @@ func TestParseEncryptionOpts(t *testing.T) {
volOptions: map[string]string{ volOptions: map[string]string{
"encrypted": "notbool", "encrypted": "notbool",
}, },
fallbackType: util.EncryptionTypeBlock, fallbackType: crypto.EncryptionTypeBlock,
expectedKMS: "", expectedKMS: "",
expectedEnc: util.EncryptionTypeInvalid, expectedEnc: crypto.EncryptionTypeInvalid,
expectedErr: true, expectedErr: true,
}, },
{ {
@ -68,9 +68,9 @@ func TestParseEncryptionOpts(t *testing.T) {
"encrypted": "true", "encrypted": "true",
"encryptionKMSID": "valid-kms-id", "encryptionKMSID": "valid-kms-id",
}, },
fallbackType: util.EncryptionTypeBlock, fallbackType: crypto.EncryptionTypeBlock,
expectedKMS: "valid-kms-id", expectedKMS: "valid-kms-id",
expectedEnc: util.EncryptionTypeBlock, expectedEnc: crypto.EncryptionTypeBlock,
expectedErr: false, expectedErr: false,
}, },
} }

View File

@ -21,6 +21,8 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/ceph/ceph-csi/pkg/util/crypto"
"github.com/ceph/ceph-csi/internal/journal" "github.com/ceph/ceph-csi/internal/journal"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/k8s" "github.com/ceph/ceph-csi/internal/util/k8s"
@ -91,14 +93,14 @@ func validateRbdVol(rbdVol *rbdVolume) error {
return err return err
} }
func getEncryptionConfig(rbdVol *rbdVolume) (string, util.EncryptionType) { func getEncryptionConfig(rbdVol *rbdVolume) (string, crypto.EncryptionType) {
switch { switch {
case rbdVol.isBlockEncrypted(): case rbdVol.isBlockEncrypted():
return rbdVol.blockEncryption.GetID(), util.EncryptionTypeBlock return rbdVol.blockEncryption.GetID(), crypto.EncryptionTypeBlock
case rbdVol.isFileEncrypted(): case rbdVol.isFileEncrypted():
return rbdVol.fileEncryption.GetID(), util.EncryptionTypeFile return rbdVol.fileEncryption.GetID(), crypto.EncryptionTypeFile
default: default:
return "", util.EncryptionTypeNone return "", crypto.EncryptionTypeNone
} }
} }
@ -145,7 +147,7 @@ func checkSnapCloneExists(
defer j.Destroy() defer j.Destroy()
snapData, err := j.CheckReservation(ctx, rbdSnap.JournalPool, 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 { if err != nil {
return false, err return false, err
} }
@ -585,7 +587,7 @@ func RegenerateJournal(
vi util.CSIIdentifier vi util.CSIIdentifier
rbdVol *rbdVolume rbdVol *rbdVolume
kmsID string kmsID string
encryptionType util.EncryptionType encryptionType crypto.EncryptionType
err error err error
ok bool ok bool
) )

View File

@ -28,6 +28,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/ceph/ceph-csi/pkg/util/crypto"
"github.com/ceph/ceph-csi/internal/rbd/types" "github.com/ceph/ceph-csi/internal/rbd/types"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/log" "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) err = rbdSnap.configureBlockEncryption(imageAttributes.KmsID, secrets)
if err != nil { if err != nil {
return rbdSnap, fmt.Errorf("failed to configure block encryption for "+ return rbdSnap, fmt.Errorf("failed to configure block encryption for "+
"%q: %w", rbdSnap, err) "%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) err = rbdSnap.configureFileEncryption(ctx, imageAttributes.KmsID, secrets)
if err != nil { if err != nil {
return rbdSnap, fmt.Errorf("failed to configure file encryption for "+ return rbdSnap, fmt.Errorf("failed to configure file encryption for "+
@ -1180,13 +1182,13 @@ func generateVolumeFromVolumeID(
rbdVol.ImageID = imageAttributes.ImageID rbdVol.ImageID = imageAttributes.ImageID
rbdVol.Owner = imageAttributes.Owner rbdVol.Owner = imageAttributes.Owner
if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == util.EncryptionTypeBlock { if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == crypto.EncryptionTypeBlock {
err = rbdVol.configureBlockEncryption(imageAttributes.KmsID, secrets) err = rbdVol.configureBlockEncryption(imageAttributes.KmsID, secrets)
if err != nil { if err != nil {
return rbdVol, err return rbdVol, err
} }
} }
if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == util.EncryptionTypeFile { if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == crypto.EncryptionTypeFile {
err = rbdVol.configureFileEncryption(ctx, imageAttributes.KmsID, secrets) err = rbdVol.configureFileEncryption(ctx, imageAttributes.KmsID, secrets)
if err != nil { if err != nil {
return rbdVol, err return rbdVol, err

View File

@ -26,6 +26,8 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/ceph/ceph-csi/pkg/util/crypto"
"github.com/ceph/ceph-csi/internal/kms" "github.com/ceph/ceph-csi/internal/kms"
"github.com/ceph/ceph-csi/internal/util/cryptsetup" "github.com/ceph/ceph-csi/internal/util/cryptsetup"
"github.com/ceph/ceph-csi/internal/util/log" "github.com/ceph/ceph-csi/internal/util/log"
@ -83,66 +85,20 @@ func FetchEncryptionKMSID(encrypted, kmsID string) (string, error) {
return kmsID, nil 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. // FetchEncryptionType returns encryptionType specified in volOptions.
// If not specified, use fallback. If specified but invalid, return // If not specified, use fallback. If specified but invalid, return
// invalid. // 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"] encType, ok := volOptions["encryptionType"]
if !ok { if !ok {
return fallback return fallback
} }
if encType == "" { if encType == "" {
return EncryptionTypeInvalid return crypto.EncryptionTypeInvalid
} }
return ParseEncryptionType(encType) return crypto.ParseEncryptionType(encType)
} }
// NewVolumeEncryption creates a new instance of VolumeEncryption and // NewVolumeEncryption creates a new instance of VolumeEncryption and

View File

@ -22,6 +22,7 @@ import (
"testing" "testing"
"github.com/ceph/ceph-csi/internal/kms" "github.com/ceph/ceph-csi/internal/kms"
"github.com/ceph/ceph-csi/pkg/util/crypto"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -65,33 +66,18 @@ func TestKMSWorkflow(t *testing.T) {
require.Equal(t, secrets["encryptionPassphrase"], passphrase) 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) { func TestFetchEncryptionType(t *testing.T) {
t.Parallel() t.Parallel()
volOpts := map[string]string{} volOpts := map[string]string{}
require.EqualValues(t, EncryptionTypeBlock, FetchEncryptionType(volOpts, EncryptionTypeBlock)) require.EqualValues(t, crypto.EncryptionTypeBlock, FetchEncryptionType(volOpts, crypto.EncryptionTypeBlock))
require.EqualValues(t, EncryptionTypeFile, FetchEncryptionType(volOpts, EncryptionTypeFile)) require.EqualValues(t, crypto.EncryptionTypeFile, FetchEncryptionType(volOpts, crypto.EncryptionTypeFile))
require.EqualValues(t, EncryptionTypeNone, FetchEncryptionType(volOpts, EncryptionTypeNone)) require.EqualValues(t, crypto.EncryptionTypeNone, FetchEncryptionType(volOpts, crypto.EncryptionTypeNone))
volOpts["encryptionType"] = "" volOpts["encryptionType"] = ""
require.EqualValues(t, EncryptionTypeInvalid, FetchEncryptionType(volOpts, EncryptionTypeNone)) require.EqualValues(t, crypto.EncryptionTypeInvalid, FetchEncryptionType(volOpts, crypto.EncryptionTypeNone))
volOpts["encryptionType"] = "block" volOpts["encryptionType"] = "block"
require.EqualValues(t, EncryptionTypeBlock, FetchEncryptionType(volOpts, EncryptionTypeNone)) require.EqualValues(t, crypto.EncryptionTypeBlock, FetchEncryptionType(volOpts, crypto.EncryptionTypeNone))
volOpts["encryptionType"] = "file" volOpts["encryptionType"] = "file"
require.EqualValues(t, EncryptionTypeFile, FetchEncryptionType(volOpts, EncryptionTypeNone)) require.EqualValues(t, crypto.EncryptionTypeFile, FetchEncryptionType(volOpts, crypto.EncryptionTypeNone))
volOpts["encryptionType"] = "INVALID" volOpts["encryptionType"] = "INVALID"
require.EqualValues(t, EncryptionTypeInvalid, FetchEncryptionType(volOpts, EncryptionTypeNone)) require.EqualValues(t, crypto.EncryptionTypeInvalid, FetchEncryptionType(volOpts, crypto.EncryptionTypeNone))
} }

63
pkg/util/crypto/types.go Normal file
View File

@ -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"
}
}

View File

@ -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())
}
}