mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-11-22 14:20:19 +00:00
rbd: store csi.storage.k8s.io/pvc/namespace metadata as Owner
The Owner of an RBD image (Kubernetes Namespace, tenant) can be used to identify additional configuration options. This will be used for fetching the right Vault Token when encrypting/decrypting volumes. Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
parent
0e6443e4c1
commit
16cb43f0f9
@ -232,7 +232,7 @@ func reserveVol(ctx context.Context, volOptions *volumeOptions, secret map[strin
|
|||||||
imageUUID, vid.FsSubvolName, err = j.ReserveName(
|
imageUUID, vid.FsSubvolName, err = j.ReserveName(
|
||||||
ctx, volOptions.MetadataPool, util.InvalidPoolID,
|
ctx, volOptions.MetadataPool, util.InvalidPoolID,
|
||||||
volOptions.MetadataPool, util.InvalidPoolID, volOptions.RequestName,
|
volOptions.MetadataPool, util.InvalidPoolID, volOptions.RequestName,
|
||||||
volOptions.NamePrefix, "", "", volOptions.ReservedID)
|
volOptions.NamePrefix, "", "", volOptions.ReservedID, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -269,7 +269,7 @@ func reserveSnap(ctx context.Context, volOptions *volumeOptions, parentSubVolNam
|
|||||||
imageUUID, vid.FsSnapshotName, err = j.ReserveName(
|
imageUUID, vid.FsSnapshotName, err = j.ReserveName(
|
||||||
ctx, volOptions.MetadataPool, util.InvalidPoolID,
|
ctx, volOptions.MetadataPool, util.InvalidPoolID,
|
||||||
volOptions.MetadataPool, util.InvalidPoolID, snap.RequestName,
|
volOptions.MetadataPool, util.InvalidPoolID, snap.RequestName,
|
||||||
snap.NamePrefix, parentSubVolName, "", snap.ReservedID)
|
snap.NamePrefix, parentSubVolName, "", snap.ReservedID, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -148,6 +148,9 @@ type Config struct {
|
|||||||
// encryptKMS in which encryption passphrase was saved, default is no encryption
|
// encryptKMS in which encryption passphrase was saved, default is no encryption
|
||||||
encryptKMSKey string
|
encryptKMSKey string
|
||||||
|
|
||||||
|
// ownerKey is used to identify the owner of the volume, can be used with some KMS configurations
|
||||||
|
ownerKey string
|
||||||
|
|
||||||
// commonPrefix is the prefix common to all omap keys for this Config
|
// commonPrefix is the prefix common to all omap keys for this Config
|
||||||
commonPrefix string
|
commonPrefix string
|
||||||
}
|
}
|
||||||
@ -165,6 +168,7 @@ func NewCSIVolumeJournal(suffix string) *Config {
|
|||||||
namespace: "",
|
namespace: "",
|
||||||
csiImageIDKey: "csi.imageid",
|
csiImageIDKey: "csi.imageid",
|
||||||
encryptKMSKey: "csi.volume.encryptKMS",
|
encryptKMSKey: "csi.volume.encryptKMS",
|
||||||
|
ownerKey: "csi.volume.owner",
|
||||||
commonPrefix: "csi.",
|
commonPrefix: "csi.",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,6 +186,7 @@ func NewCSISnapshotJournal(suffix string) *Config {
|
|||||||
namespace: "",
|
namespace: "",
|
||||||
csiImageIDKey: "csi.imageid",
|
csiImageIDKey: "csi.imageid",
|
||||||
encryptKMSKey: "csi.volume.encryptKMS",
|
encryptKMSKey: "csi.volume.encryptKMS",
|
||||||
|
ownerKey: "csi.volume.owner",
|
||||||
commonPrefix: "csi.",
|
commonPrefix: "csi.",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,6 +499,7 @@ Input arguments:
|
|||||||
- kmsConf: Name of the key management service used to encrypt the image (optional)
|
- kmsConf: Name of the key management service used to encrypt the image (optional)
|
||||||
- volUUID: UUID need to be reserved instead of auto-generating one (this is
|
- volUUID: UUID need to be reserved instead of auto-generating one (this is
|
||||||
useful for mirroring and metro-DR)
|
useful for mirroring and metro-DR)
|
||||||
|
- owner: the owner of the volume (optional)
|
||||||
|
|
||||||
Return values:
|
Return values:
|
||||||
- string: Contains the UUID that was reserved for the passed in reqName
|
- string: Contains the UUID that was reserved for the passed in reqName
|
||||||
@ -503,7 +509,7 @@ Return values:
|
|||||||
func (conn *Connection) ReserveName(ctx context.Context,
|
func (conn *Connection) ReserveName(ctx context.Context,
|
||||||
journalPool string, journalPoolID int64,
|
journalPool string, journalPoolID int64,
|
||||||
imagePool string, imagePoolID int64,
|
imagePool string, imagePoolID int64,
|
||||||
reqName, namePrefix, parentName, kmsConf, volUUID string) (string, string, error) {
|
reqName, namePrefix, parentName, kmsConf, volUUID, owner string) (string, string, error) {
|
||||||
// TODO: Take in-arg as ImageAttributes?
|
// TODO: Take in-arg as ImageAttributes?
|
||||||
var (
|
var (
|
||||||
snapSource bool
|
snapSource bool
|
||||||
@ -574,6 +580,11 @@ func (conn *Connection) ReserveName(ctx context.Context,
|
|||||||
omapValues[cj.encryptKMSKey] = kmsConf
|
omapValues[cj.encryptKMSKey] = kmsConf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if owner is passed, set it in the UUID directory too
|
||||||
|
if owner != "" {
|
||||||
|
omapValues[cj.ownerKey] = owner
|
||||||
|
}
|
||||||
|
|
||||||
if journalPool != imagePool && journalPoolID != util.InvalidPoolID {
|
if journalPool != imagePool && journalPoolID != util.InvalidPoolID {
|
||||||
buf64 := make([]byte, 8)
|
buf64 := make([]byte, 8)
|
||||||
binary.BigEndian.PutUint64(buf64, uint64(journalPoolID))
|
binary.BigEndian.PutUint64(buf64, uint64(journalPoolID))
|
||||||
@ -601,6 +612,7 @@ type ImageAttributes struct {
|
|||||||
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
|
||||||
|
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
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -625,6 +637,7 @@ func (conn *Connection) GetImageAttributes(ctx context.Context, pool, objectUUID
|
|||||||
cj.csiJournalPool,
|
cj.csiJournalPool,
|
||||||
cj.cephSnapSourceKey,
|
cj.cephSnapSourceKey,
|
||||||
cj.csiImageIDKey,
|
cj.csiImageIDKey,
|
||||||
|
cj.ownerKey,
|
||||||
}
|
}
|
||||||
values, err := getOMapValues(
|
values, err := getOMapValues(
|
||||||
ctx, conn, pool, cj.namespace, cj.cephUUIDDirectoryPrefix+objectUUID,
|
ctx, conn, pool, cj.namespace, cj.cephUUIDDirectoryPrefix+objectUUID,
|
||||||
@ -639,6 +652,7 @@ func (conn *Connection) GetImageAttributes(ctx context.Context, pool, objectUUID
|
|||||||
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.Owner = values[cj.ownerKey]
|
||||||
imageAttributes.ImageID = values[cj.csiImageIDKey]
|
imageAttributes.ImageID = values[cj.csiImageIDKey]
|
||||||
|
|
||||||
// image key was added at a later point, so not all volumes will have this
|
// image key was added at a later point, so not all volumes will have this
|
||||||
|
@ -344,7 +344,7 @@ func reserveSnap(ctx context.Context, rbdSnap *rbdSnapshot, rbdVol *rbdVolume, c
|
|||||||
|
|
||||||
rbdSnap.ReservedID, rbdSnap.RbdSnapName, err = j.ReserveName(
|
rbdSnap.ReservedID, rbdSnap.RbdSnapName, err = j.ReserveName(
|
||||||
ctx, rbdSnap.JournalPool, journalPoolID, rbdSnap.Pool, imagePoolID,
|
ctx, rbdSnap.JournalPool, journalPoolID, rbdSnap.Pool, imagePoolID,
|
||||||
rbdSnap.RequestName, rbdSnap.NamePrefix, rbdVol.RbdImageName, "", rbdSnap.ReservedID)
|
rbdSnap.RequestName, rbdSnap.NamePrefix, rbdVol.RbdImageName, "", rbdSnap.ReservedID, rbdVol.Owner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -422,7 +422,7 @@ func reserveVol(ctx context.Context, rbdVol *rbdVolume, rbdSnap *rbdSnapshot, cr
|
|||||||
|
|
||||||
rbdVol.ReservedID, rbdVol.RbdImageName, err = j.ReserveName(
|
rbdVol.ReservedID, rbdVol.RbdImageName, err = j.ReserveName(
|
||||||
ctx, rbdVol.JournalPool, journalPoolID, rbdVol.Pool, imagePoolID,
|
ctx, rbdVol.JournalPool, journalPoolID, rbdVol.Pool, imagePoolID,
|
||||||
rbdVol.RequestName, rbdVol.NamePrefix, "", kmsID, rbdVol.ReservedID)
|
rbdVol.RequestName, rbdVol.NamePrefix, "", kmsID, rbdVol.ReservedID, rbdVol.Owner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -542,6 +542,7 @@ func RegenerateJournal(imageName, volumeID, pool, journalPool, requestName strin
|
|||||||
if imageData != nil {
|
if imageData != nil {
|
||||||
rbdVol.ReservedID = imageData.ImageUUID
|
rbdVol.ReservedID = imageData.ImageUUID
|
||||||
rbdVol.ImageID = imageData.ImageAttributes.ImageID
|
rbdVol.ImageID = imageData.ImageAttributes.ImageID
|
||||||
|
rbdVol.Owner = imageData.ImageAttributes.Owner
|
||||||
if rbdVol.ImageID == "" {
|
if rbdVol.ImageID == "" {
|
||||||
err = rbdVol.storeImageID(ctx, j)
|
err = rbdVol.storeImageID(ctx, j)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -559,7 +560,7 @@ func RegenerateJournal(imageName, volumeID, pool, journalPool, requestName strin
|
|||||||
|
|
||||||
rbdVol.ReservedID, rbdVol.RbdImageName, err = j.ReserveName(
|
rbdVol.ReservedID, rbdVol.RbdImageName, err = j.ReserveName(
|
||||||
ctx, rbdVol.JournalPool, journalPoolID, rbdVol.Pool, imagePoolID,
|
ctx, rbdVol.JournalPool, journalPoolID, rbdVol.Pool, imagePoolID,
|
||||||
rbdVol.RequestName, rbdVol.NamePrefix, "", kmsID, vi.ObjectUUID)
|
rbdVol.RequestName, rbdVol.NamePrefix, "", kmsID, vi.ObjectUUID, rbdVol.Owner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,9 @@ type rbdVolume struct {
|
|||||||
readOnly bool
|
readOnly bool
|
||||||
Primary bool
|
Primary bool
|
||||||
KMS util.EncryptionKMS
|
KMS util.EncryptionKMS
|
||||||
CreatedAt *timestamp.Timestamp
|
// Owner is the creator (tenant, Kubernetes Namespace) of the volume.
|
||||||
|
Owner string
|
||||||
|
CreatedAt *timestamp.Timestamp
|
||||||
// conn is a connection to the Ceph cluster obtained from a ConnPool
|
// conn is a connection to the Ceph cluster obtained from a ConnPool
|
||||||
conn *util.ClusterConnection
|
conn *util.ClusterConnection
|
||||||
// an opened IOContext, call .openIoctx() before using
|
// an opened IOContext, call .openIoctx() before using
|
||||||
@ -734,6 +736,7 @@ func genVolFromVolID(ctx context.Context, volumeID string, cr *util.Credentials,
|
|||||||
rbdVol.RbdImageName = imageAttributes.ImageName
|
rbdVol.RbdImageName = imageAttributes.ImageName
|
||||||
rbdVol.ReservedID = vi.ObjectUUID
|
rbdVol.ReservedID = vi.ObjectUUID
|
||||||
rbdVol.ImageID = imageAttributes.ImageID
|
rbdVol.ImageID = imageAttributes.ImageID
|
||||||
|
rbdVol.Owner = imageAttributes.Owner
|
||||||
|
|
||||||
if imageAttributes.KmsID != "" {
|
if imageAttributes.KmsID != "" {
|
||||||
rbdVol.Encrypted = true
|
rbdVol.Encrypted = true
|
||||||
@ -813,6 +816,15 @@ func genVolFromVolumeOptions(ctx context.Context, volOptions, credentials map[st
|
|||||||
rbdVol.Mounter = rbdDefaultMounter
|
rbdVol.Mounter = rbdDefaultMounter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the KMS is of type VaultToken, additional metadata is needed
|
||||||
|
// depending on the tenant, the KMS can be configured with other
|
||||||
|
// options
|
||||||
|
// FIXME: this works only on Kubernetes, how do other CO supply metadata?
|
||||||
|
rbdVol.Owner, ok = volOptions["csi.storage.k8s.io/pvc/namespace"]
|
||||||
|
if !ok {
|
||||||
|
util.DebugLog(ctx, "could not detect owner for %s", rbdVol.String())
|
||||||
|
}
|
||||||
|
|
||||||
rbdVol.Encrypted = false
|
rbdVol.Encrypted = false
|
||||||
encrypted, ok = volOptions["encrypted"]
|
encrypted, ok = volOptions["encrypted"]
|
||||||
if ok {
|
if ok {
|
||||||
|
Loading…
Reference in New Issue
Block a user