util: move GetID() from EncryptionKMS to VolumeEncryption

There is no need for each EncryptionKMS to implement the same GetID()
function. We have a VolumeEncryption type that is more suitable for
keeping track of the KMS-ID that was used to get the configuration of
the KMS.

This does not change any metadata that is stored anywhere.

Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
Niels de Vos 2021-03-19 16:21:48 +01:00 committed by mergify[bot]
parent 9317e2afb4
commit eea97ca014
10 changed files with 38 additions and 46 deletions

View File

@ -208,7 +208,7 @@ func (ri *rbdImage) configureEncryption(kmsID string, credentials map[string]str
return err return err
} }
ri.encryption, err = util.NewVolumeEncryption(kms) ri.encryption, err = util.NewVolumeEncryption(kmsID, kms)
// if the KMS can not store the DEK itself, we'll store it in the // if the KMS can not store the DEK itself, we'll store it in the
// metadata of the RBD image itself // metadata of the RBD image itself

View File

@ -234,7 +234,7 @@ func (rv *rbdVolume) Exists(ctx context.Context, parentVol *rbdVolume) (bool, er
kmsID := "" kmsID := ""
if rv.isEncrypted() { if rv.isEncrypted() {
kmsID = rv.encryption.KMS.GetID() kmsID = rv.encryption.GetID()
} }
j, err := volJournal.Connect(rv.Monitors, rv.RadosNamespace, rv.conn.Creds) j, err := volJournal.Connect(rv.Monitors, rv.RadosNamespace, rv.conn.Creds)
@ -411,7 +411,7 @@ func reserveVol(ctx context.Context, rbdVol *rbdVolume, rbdSnap *rbdSnapshot, cr
kmsID := "" kmsID := ""
if rbdVol.isEncrypted() { if rbdVol.isEncrypted() {
kmsID = rbdVol.encryption.KMS.GetID() kmsID = rbdVol.encryption.GetID()
} }
j, err := volJournal.Connect(rbdVol.Monitors, rbdVol.RadosNamespace, cr) j, err := volJournal.Connect(rbdVol.Monitors, rbdVol.RadosNamespace, cr)

View File

@ -57,6 +57,8 @@ type VolumeEncryption struct {
// dekStore that will be used, this can be the EncryptionKMS or a // dekStore that will be used, this can be the EncryptionKMS or a
// different object implementing the DEKStore interface. // different object implementing the DEKStore interface.
dekStore DEKStore dekStore DEKStore
id string
} }
// NewVolumeEncryption creates a new instance of VolumeEncryption and // NewVolumeEncryption creates a new instance of VolumeEncryption and
@ -65,8 +67,18 @@ type VolumeEncryption struct {
// Callers that receive a ErrDEKStoreNeeded error, should use // Callers that receive a ErrDEKStoreNeeded error, should use
// VolumeEncryption.SetDEKStore() to configure an alternative storage for the // VolumeEncryption.SetDEKStore() to configure an alternative storage for the
// DEKs. // DEKs.
func NewVolumeEncryption(kms EncryptionKMS) (*VolumeEncryption, error) { func NewVolumeEncryption(id string, kms EncryptionKMS) (*VolumeEncryption, error) {
ve := &VolumeEncryption{KMS: kms} kmsID := id
if kmsID == "" {
// if kmsID is not set, encryption is enabled, and the type is
// SecretsKMS
kmsID = defaultKMSType
}
ve := &VolumeEncryption{
id: kmsID,
KMS: kms,
}
if kms.requiresDEKStore() == DEKStoreIntegrated { if kms.requiresDEKStore() == DEKStoreIntegrated {
dekStore, ok := kms.(DEKStore) dekStore, ok := kms.(DEKStore)
@ -103,11 +115,14 @@ func (ve *VolumeEncryption) RemoveDEK(volumeID string) error {
return ve.dekStore.RemoveDEK(volumeID) return ve.dekStore.RemoveDEK(volumeID)
} }
func (ve *VolumeEncryption) GetID() string {
return ve.id
}
// EncryptionKMS provides external Key Management System for encryption // EncryptionKMS provides external Key Management System for encryption
// passphrases storage. // passphrases storage.
type EncryptionKMS interface { type EncryptionKMS interface {
Destroy() Destroy()
GetID() string
// requiresDEKStore returns the DEKStoreType that is needed to be // requiresDEKStore returns the DEKStoreType that is needed to be
// configure for the KMS. Nothing needs to be done when this function // configure for the KMS. Nothing needs to be done when this function

View File

@ -58,11 +58,11 @@ func TestKMSWorkflow(t *testing.T) {
kms, err := GetKMS("tenant", defaultKMSType, secrets) kms, err := GetKMS("tenant", defaultKMSType, secrets)
assert.NoError(t, err) assert.NoError(t, err)
require.NotNil(t, kms) require.NotNil(t, kms)
assert.Equal(t, defaultKMSType, kms.GetID())
ve, err := NewVolumeEncryption(kms) ve, err := NewVolumeEncryption("", kms)
assert.NoError(t, err) assert.NoError(t, err)
require.NotNil(t, ve) require.NotNil(t, ve)
assert.Equal(t, defaultKMSType, ve.GetID())
volumeID := "volume-id" volumeID := "volume-id"

View File

@ -76,7 +76,7 @@ func GetKMS(tenant, kmsID string, secrets map[string]string) (EncryptionKMS, err
"section: %s", kmsID) "section: %s", kmsID)
} }
return kmsManager.buildKMS(kmsID, tenant, kmsConfig, secrets) return kmsManager.buildKMS(tenant, kmsConfig, secrets)
} }
// getKMSConfiguration reads the configuration file from the filesystem, or if // getKMSConfiguration reads the configuration file from the filesystem, or if
@ -181,9 +181,9 @@ func getKMSProvider(config map[string]interface{}) (string, error) {
// KMSInitializerArgs get passed to KMSInitializerFunc when a new instance of a // KMSInitializerArgs get passed to KMSInitializerFunc when a new instance of a
// KMSProvider is initialized. // KMSProvider is initialized.
type KMSInitializerArgs struct { type KMSInitializerArgs struct {
ID, Tenant string Tenant string
Config map[string]interface{} Config map[string]interface{}
Secrets map[string]string Secrets map[string]string
} }
// KMSInitializerFunc gets called when the KMSProvider needs to be // KMSInitializerFunc gets called when the KMSProvider needs to be
@ -225,7 +225,10 @@ func RegisterKMSProvider(provider KMSProvider) bool {
return true return true
} }
func (kf *kmsProviderList) buildKMS(kmsID, tenant string, config map[string]interface{}, secrets map[string]string) (EncryptionKMS, error) { // buildKMS creates a new KMSProvider instance, based on the configuration that
// was passed. This uses getKMSProvider() internally to identify the
// KMSProvider to instantiate.
func (kf *kmsProviderList) buildKMS(tenant string, config map[string]interface{}, secrets map[string]string) (EncryptionKMS, error) {
providerName, err := getKMSProvider(config) providerName, err := getKMSProvider(config)
if err != nil { if err != nil {
return nil, err return nil, err
@ -238,7 +241,6 @@ func (kf *kmsProviderList) buildKMS(kmsID, tenant string, config map[string]inte
} }
return provider.Initializer(KMSInitializerArgs{ return provider.Initializer(KMSInitializerArgs{
ID: kmsID,
Tenant: tenant, Tenant: tenant,
Config: config, Config: config,
Secrets: secrets, Secrets: secrets,

View File

@ -58,11 +58,6 @@ func initSecretsKMS(secrets map[string]string) (EncryptionKMS, error) {
return SecretsKMS{passphrase: passphraseValue}, nil return SecretsKMS{passphrase: passphraseValue}, nil
} }
// GetID is returning ID representing default KMS `default`.
func (kms SecretsKMS) GetID() string {
return defaultKMSType
}
// Destroy frees all used resources. // Destroy frees all used resources.
func (kms SecretsKMS) Destroy() { func (kms SecretsKMS) Destroy() {
// nothing to do // nothing to do
@ -89,8 +84,6 @@ func (kms SecretsKMS) RemoveDEK(key string) error {
// Data-Encryption-Key (DEK) in the metadata of the volume. // Data-Encryption-Key (DEK) in the metadata of the volume.
type SecretsMetadataKMS struct { type SecretsMetadataKMS struct {
SecretsKMS SecretsKMS
encryptionKMSID string
} }
var _ = RegisterKMSProvider(KMSProvider{ var _ = RegisterKMSProvider(KMSProvider{
@ -114,16 +107,10 @@ func initSecretsMetadataKMS(args KMSInitializerArgs) (EncryptionKMS, error) {
smKMS := SecretsMetadataKMS{} smKMS := SecretsMetadataKMS{}
smKMS.SecretsKMS = sKMS smKMS.SecretsKMS = sKMS
smKMS.encryptionKMSID = args.ID
return smKMS, nil return smKMS, nil
} }
// GetID is returning ID representing the SecretsMetadataKMS.
func (kms SecretsMetadataKMS) GetID() string {
return kms.encryptionKMSID
}
// Destroy frees all used resources. // Destroy frees all used resources.
func (kms SecretsMetadataKMS) Destroy() { func (kms SecretsMetadataKMS) Destroy() {
kms.SecretsKMS.Destroy() kms.SecretsKMS.Destroy()

View File

@ -42,7 +42,6 @@ func TestGenerateCipher(t *testing.T) {
func TestInitSecretsMetadataKMS(t *testing.T) { func TestInitSecretsMetadataKMS(t *testing.T) {
args := KMSInitializerArgs{ args := KMSInitializerArgs{
ID: "secrets-metadata-unit-test",
Tenant: "tenant", Tenant: "tenant",
Config: nil, Config: nil,
Secrets: map[string]string{}, Secrets: map[string]string{},
@ -59,7 +58,6 @@ func TestInitSecretsMetadataKMS(t *testing.T) {
kms, err = initSecretsMetadataKMS(args) kms, err = initSecretsMetadataKMS(args)
assert.NoError(t, err) assert.NoError(t, err)
require.NotNil(t, kms) require.NotNil(t, kms)
assert.Equal(t, "secrets-metadata-unit-test", kms.GetID())
assert.Equal(t, DEKStoreMetadata, kms.requiresDEKStore()) assert.Equal(t, DEKStoreMetadata, kms.requiresDEKStore())
} }
@ -68,7 +66,6 @@ func TestWorkflowSecretsMetadataKMS(t *testing.T) {
encryptionPassphraseKey: "my-passphrase-from-kubernetes", encryptionPassphraseKey: "my-passphrase-from-kubernetes",
} }
args := KMSInitializerArgs{ args := KMSInitializerArgs{
ID: "secrets-metadata-unit-test",
Tenant: "tenant", Tenant: "tenant",
Config: nil, Config: nil,
Secrets: secrets, Secrets: secrets,

View File

@ -71,10 +71,9 @@ Example JSON structure in the KMS config is,
*/ */
type vaultConnection struct { type vaultConnection struct {
EncryptionKMSID string secrets loss.Secrets
secrets loss.Secrets vaultConfig map[string]interface{}
vaultConfig map[string]interface{} keyContext map[string]string
keyContext map[string]string
} }
type VaultKMS struct { type VaultKMS struct {
@ -114,12 +113,10 @@ func setConfigString(option *string, config map[string]interface{}, key string)
// vc.connectVault(). // vc.connectVault().
// //
// nolint:gocyclo // iterating through many config options, not complex at all. // nolint:gocyclo // iterating through many config options, not complex at all.
func (vc *vaultConnection) initConnection(kmsID string, config map[string]interface{}) error { func (vc *vaultConnection) initConnection(config map[string]interface{}) error {
vaultConfig := make(map[string]interface{}) vaultConfig := make(map[string]interface{})
keyContext := make(map[string]string) keyContext := make(map[string]string)
vc.EncryptionKMSID = kmsID
firstInit := (vc.vaultConfig == nil) firstInit := (vc.vaultConfig == nil)
vaultAddress := "" // required vaultAddress := "" // required
@ -268,7 +265,7 @@ var _ = RegisterKMSProvider(KMSProvider{
// InitVaultKMS returns an interface to HashiCorp Vault KMS. // InitVaultKMS returns an interface to HashiCorp Vault KMS.
func initVaultKMS(args KMSInitializerArgs) (EncryptionKMS, error) { func initVaultKMS(args KMSInitializerArgs) (EncryptionKMS, error) {
kms := &VaultKMS{} kms := &VaultKMS{}
err := kms.initConnection(args.ID, args.Config) err := kms.initConnection(args.Config)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to initialize Vault connection: %w", err) return nil, fmt.Errorf("failed to initialize Vault connection: %w", err)
} }
@ -328,11 +325,6 @@ func initVaultKMS(args KMSInitializerArgs) (EncryptionKMS, error) {
return kms, nil return kms, nil
} }
// GetID is returning correlation ID to KMS configuration.
func (vc *vaultConnection) GetID() string {
return vc.EncryptionKMSID
}
// FetchDEK returns passphrase from Vault. The passphrase is stored in a // FetchDEK returns passphrase from Vault. The passphrase is stored in a
// data.data.passphrase structure. // data.data.passphrase structure.
func (kms *VaultKMS) FetchDEK(key string) (string, error) { func (kms *VaultKMS) FetchDEK(key string) (string, error) {

View File

@ -199,7 +199,7 @@ func initVaultTokensKMS(args KMSInitializerArgs) (EncryptionKMS, error) {
} }
kms := &VaultTokensKMS{} kms := &VaultTokensKMS{}
err = kms.initConnection(args.ID, args.Config) err = kms.initConnection(args.Config)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to initialize Vault connection: %w", err) return nil, fmt.Errorf("failed to initialize Vault connection: %w", err)
} }
@ -263,7 +263,7 @@ func initVaultTokensKMS(args KMSInitializerArgs) (EncryptionKMS, error) {
// secrets. This method can be called multiple times, i.e. to override // secrets. This method can be called multiple times, i.e. to override
// configuration options from tenants. // configuration options from tenants.
func (kms *VaultTokensKMS) parseConfig(config map[string]interface{}) error { func (kms *VaultTokensKMS) parseConfig(config map[string]interface{}) error {
err := kms.initConnection(kms.EncryptionKMSID, config) err := kms.initConnection(config)
if err != nil { if err != nil {
return err return err
} }

View File

@ -78,7 +78,6 @@ func TestInitVaultTokensKMS(t *testing.T) {
} }
args := KMSInitializerArgs{ args := KMSInitializerArgs{
ID: "vault-tokens-config",
Tenant: "bob", Tenant: "bob",
Config: make(map[string]interface{}), Config: make(map[string]interface{}),
Secrets: nil, Secrets: nil,