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
committed by mergify[bot]
parent ac38963cbf
commit 542ed3de63
12 changed files with 207 additions and 151 deletions

View File

@ -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,

View File

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

View File

@ -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]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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