mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-11-25 15:50:20 +00:00
rbd: read configuration from the configmap
if the kms encryption configmap is not mounted as a volume to the CSI pods, add the code to read the configuration from the kubernetes. Later the code to fetch the configmap will be moved to the new sidecar which is will talk to respective CO to fetch the encryption configurations. The k8s configmap uses the standard vault spefic names to add the configurations. this will be converted back to the CSI configurations. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
parent
e4b16a5c72
commit
b3fbcb9c95
@ -133,6 +133,12 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
# - name: POD_NAMESPACE
|
||||
# valueFrom:
|
||||
# fieldRef:
|
||||
# fieldPath: spec.namespace
|
||||
# - name: KMS_CONFIGMAP_NAME
|
||||
# value: encryptionConfig
|
||||
- name: CSI_ENDPOINT
|
||||
value: unix:///csi/csi-provisioner.sock
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
|
@ -69,6 +69,12 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
# - name: POD_NAMESPACE
|
||||
# valueFrom:
|
||||
# fieldRef:
|
||||
# fieldPath: spec.namespace
|
||||
# - name: KMS_CONFIGMAP_NAME
|
||||
# value: encryptionConfig
|
||||
- name: CSI_ENDPOINT
|
||||
value: unix:///csi/csi.sock
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
@ -46,6 +47,14 @@ const (
|
||||
// Passphrase size - 20 bytes is 160 bits to satisfy:
|
||||
// https://tools.ietf.org/html/rfc6749#section-10.10
|
||||
encryptionPassphraseSize = 20
|
||||
// podNamespace ENV should be set in the cephcsi container
|
||||
podNamespace = "POD_NAMESPACE"
|
||||
|
||||
// kmsConfigMapName env to read a ConfigMap by name
|
||||
kmsConfigMapName = "KMS_CONFIGMAP_NAME"
|
||||
|
||||
// defaultConfigMapToRead default ConfigMap name to fetch kms connection details
|
||||
defaultConfigMapToRead = "csi-kms-connection-details"
|
||||
)
|
||||
|
||||
// EncryptionKMS provides external Key Management System for encryption
|
||||
@ -113,18 +122,34 @@ func GetKMS(tenant, kmsID string, secrets map[string]string) (EncryptionKMS, err
|
||||
if kmsID == "" || kmsID == defaultKMSType {
|
||||
return initSecretsKMS(secrets)
|
||||
}
|
||||
|
||||
var config map[string]interface{}
|
||||
// #nosec
|
||||
content, err := ioutil.ReadFile(kmsConfigPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read kms configuration from %s: %s",
|
||||
kmsConfigPath, err)
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("failed to read kms configuration from %s: %w",
|
||||
kmsConfigPath, err)
|
||||
}
|
||||
// If the configmap is not mounted to the CSI pods read the configmap
|
||||
// the kubernetes.
|
||||
namespace := os.Getenv(podNamespace)
|
||||
if namespace != "" {
|
||||
return nil, fmt.Errorf("%q is not set", podNamespace)
|
||||
}
|
||||
name := os.Getenv(kmsConfigMapName)
|
||||
if name != "" {
|
||||
name = defaultConfigMapToRead
|
||||
}
|
||||
config, err = getVaultConfiguration(namespace, name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read kms configuration from configmap %s in namespace %s: %w",
|
||||
namespace, name, err)
|
||||
}
|
||||
}
|
||||
|
||||
var config map[string]interface{}
|
||||
err = json.Unmarshal(content, &config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse kms configuration: %s", err)
|
||||
return nil, fmt.Errorf("failed to parse kms configuration: %w", err)
|
||||
}
|
||||
|
||||
kmsConfig, ok := config[kmsID].(map[string]interface{})
|
||||
|
@ -18,6 +18,7 @@ package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -52,6 +53,73 @@ const (
|
||||
vaultTokenSecretKey = "token"
|
||||
)
|
||||
|
||||
type standardVault struct {
|
||||
KmsPROVIDER string `json:"KMS_PROVIDER"`
|
||||
VaultADDR string `json:"VAULT_ADDR"`
|
||||
VaultBackendPath string `json:"VAULT_BACKEND_PATH"`
|
||||
VaultCACert string `json:"VAULT_CACERT"`
|
||||
VaultTLSServerName string `json:"VAULT_TLS_SERVER_NAME"`
|
||||
VaultClientCert string `json:"VAULT_CLIENT_CERT"`
|
||||
VaultClientKey string `json:"VAULT_CLIENT_KEY"`
|
||||
VaultNamespace string `json:"VAULT_NAMESPACE"`
|
||||
}
|
||||
|
||||
type vaultTokenConf struct {
|
||||
EncryptionKMSType string `json:"encryptionKMSType"`
|
||||
VaultAddress string `json:"vaultAddress"`
|
||||
VaultBackendPath string `json:"vaultBackendPath"`
|
||||
VaultCAFromSecret string `json:"vaultCAFromSecret"`
|
||||
VaultTLSServerName string `json:"vaultTLSServerName"`
|
||||
VaultClientCertFromSecret string `json:"vaultClientCertFromSecret"`
|
||||
VaultClientCertKeyFromSecret string `json:"vaultClientCertKeyFromSecret"`
|
||||
VaultNamespace string `json:"vaultNamespace"`
|
||||
}
|
||||
|
||||
func (v *vaultTokenConf) convertStdVaultToCSIConfig(s *standardVault) {
|
||||
v.EncryptionKMSType = s.KmsPROVIDER
|
||||
v.VaultAddress = s.VaultADDR
|
||||
v.VaultBackendPath = s.VaultBackendPath
|
||||
v.VaultCAFromSecret = s.VaultCACert
|
||||
v.VaultClientCertFromSecret = s.VaultClientCert
|
||||
v.VaultClientCertKeyFromSecret = s.VaultClientKey
|
||||
v.VaultNamespace = s.VaultNamespace
|
||||
v.VaultTLSServerName = s.VaultTLSServerName
|
||||
}
|
||||
|
||||
// getVaultConfiguration fetches the vault configuration from the kubernetes
|
||||
// configmap and converts the standard vault configuration (see json tag of
|
||||
// standardVault structure) to the CSI vault configuration.
|
||||
func getVaultConfiguration(namespace, name string) (map[string]interface{}, error) {
|
||||
c := NewK8sClient()
|
||||
cm, err := c.CoreV1().ConfigMaps(namespace).Get(context.Background(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config := make(map[string]interface{})
|
||||
// convert the standard vault configuration to CSI vault configuration and
|
||||
// store it in the map that CSI expects
|
||||
for k, v := range cm.Data {
|
||||
sv := &standardVault{}
|
||||
err = json.Unmarshal([]byte(v), sv)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to Unmarshal the vault configuration for %q: %w", k, err)
|
||||
}
|
||||
vc := vaultTokenConf{}
|
||||
vc.convertStdVaultToCSIConfig(sv)
|
||||
data, err := json.Marshal(vc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to Marshal the CSI vault configuration for %q: %w", k, err)
|
||||
}
|
||||
jsonMap := make(map[string]interface{})
|
||||
err = json.Unmarshal(data, &jsonMap)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to Unmarshal the CSI vault configuration for %q: %w", k, err)
|
||||
}
|
||||
config[k] = jsonMap
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
/*
|
||||
VaultTokens represents a Hashicorp Vault KMS configuration that provides a
|
||||
Token per tenant.
|
||||
|
Loading…
Reference in New Issue
Block a user