Skip to content

Commit

Permalink
util: allow tenants to (re)configure VaultTokens settings
Browse files Browse the repository at this point in the history
A tenant can place a ConfigMap in their Kubernetes Namespace with
configuration options that differ from the global (by the Storage Admin
set) values.

The ConfigMap needs to be located in the Tenants namespace, as described
in the documentation

See-also: docs/design/proposals/encryption-with-vault-tokens.md
Signed-off-by: Niels de Vos <ndevos@redhat.com>
  • Loading branch information
nixpanic authored and mergify[bot] committed Dec 16, 2020
1 parent 81061e9 commit e4b16a5
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
12 changes: 12 additions & 0 deletions examples/kms/vault/tenant-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
# This is an optional (re)configuration of the connection to the Vault
# Service that can be created in a Kubernetes Namespace for a Tenant.
apiVersion: v1
kind: ConfigMap
metadata:
name: ceph-csi-kms-config
data:
vaultAddress: "http://vault.default.svc.cluster.local:8200"
vaultBackendPath: "secret/"
vaultTLSServerName: "vault.default.svc.cluster.local"
vaultCAVerify: "false"
64 changes: 64 additions & 0 deletions internal/util/vault_tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ func InitVaultTokensKMS(tenant, kmsID string, config map[string]interface{}) (En
}
}
}

err = kms.parseTenantConfig()
if err != nil {
return nil, fmt.Errorf("failed to parse config for tenant: %w", err)
}
}

// fetch the Vault Token from the Secret (TokenName) in the Kubernetes
Expand Down Expand Up @@ -339,3 +344,62 @@ func getCertificate(tenant, secretName, key string) (string, error) {

return string(cert), nil
}

// isTenantConfigOption return true if a tenant may (re)configure the option in
// their own ConfigMap, false otherwise.
func isTenantConfigOption(opt string) bool {
switch opt {
case "vaultAddress":
case "vaultBackendPath":
case "vaultTLSServerName":
case "vaultCAFromSecret":
case "vaultCAVerify":
default:
return false
}

return true
}

// parseTenantConfig gets the optional ConfigMap from the Tenants namespace,
// and applies the allowable options (see isTenantConfigOption) to the KMS
// configuration.
func (kms *VaultTokensKMS) parseTenantConfig() error {
if kms.Tenant == "" || kms.ConfigName == "" {
return nil
}

// fetch the ConfigMap from the tanants namespace
c := NewK8sClient()
cm, err := c.CoreV1().ConfigMaps(kms.Tenant).Get(context.TODO(),
kms.ConfigName, metav1.GetOptions{})
if apierrs.IsNotFound(err) {
// the tenant did not (re)configure any options
return nil
} else if err != nil {
return fmt.Errorf("failed to get config (%s) for tenant (%s): %w",
kms.ConfigName, kms.Tenant, err)
}

// create a new map with config options, but only include the options
// that a tenant may (re)configure
config := make(map[string]interface{})
for k, v := range cm.Data {
if isTenantConfigOption(k) {
config[k] = v
} // else: silently ignore the option
}
if len(config) == 0 {
// no options configured by the tenant
return nil
}

// apply the configuration options from the tenant
err = kms.parseConfig(config)
if err != nil {
return fmt.Errorf("failed to parse config (%s) for tenant (%s): %w",
kms.ConfigName, kms.Tenant, err)
}

return nil
}

0 comments on commit e4b16a5

Please sign in to comment.