diff --git a/internal/util/vault.go b/internal/util/vault.go index 91b5fd90b..79e377650 100644 --- a/internal/util/vault.go +++ b/internal/util/vault.go @@ -39,6 +39,7 @@ const ( // vault configuration defaults. vaultDefaultAuthPath = "/v1/auth/kubernetes/login" + vaultDefaultAuthMountPath = "kubernetes" // main component of vaultAuthPath vaultDefaultRole = "csi-kubernetes" vaultDefaultNamespace = "" vaultDefaultPassphrasePath = "" diff --git a/internal/util/vault_sa.go b/internal/util/vault_sa.go index 8ad379a79..c8940ea03 100644 --- a/internal/util/vault_sa.go +++ b/internal/util/vault_sa.go @@ -110,6 +110,9 @@ func initVaultTenantSA(args KMSInitializerArgs) (EncryptionKMS, error) { kms.ConfigName = vaultTokensDefaultConfigName kms.tenantSAName = vaultTenantSAName + // "vaultAuthPath" is configurable per tenant + kms.vaultConfig[vault.AuthMountPath] = vaultDefaultAuthMountPath + // "vaultRole" is configurable per tenant kms.vaultConfig[vault.AuthKubernetesRole] = vaultDefaultRole @@ -197,6 +200,18 @@ func (kms *VaultTenantSA) parseConfig(config map[string]interface{}) error { kms.ConfigName, kms.Tenant, err) } + // default vaultAuthPath is set in initVaultTenantSA() + var vaultAuthPath string + err = setConfigString(&vaultAuthPath, config, "vaultAuthPath") + if errors.Is(err, errConfigOptionInvalid) { + return err + } else if err == nil { + kms.vaultConfig[vault.AuthMountPath], err = detectAuthMountPath(vaultAuthPath) + if err != nil { + return fmt.Errorf("failed to set %s in Vault config: %w", vault.AuthMountPath, err) + } + } + // default vaultRole is set in initVaultTenantSA() var vaultRole string err = setConfigString(&vaultRole, config, "vaultRole") @@ -222,6 +237,7 @@ func isTenantSAConfigOption(opt string) bool { // additional options for VaultTenantSA switch opt { case "tenantSAName": + case "vaultAuthPath": case "vaultRole": default: return false diff --git a/internal/util/vault_sa_test.go b/internal/util/vault_sa_test.go index dfa89e235..789d42b3f 100644 --- a/internal/util/vault_sa_test.go +++ b/internal/util/vault_sa_test.go @@ -17,6 +17,7 @@ limitations under the License. package util import ( + "errors" "testing" "github.com/stretchr/testify/assert" @@ -27,3 +28,50 @@ func TestVaultTenantSAKMSRegistered(t *testing.T) { _, ok := kmsManager.providers[kmsTypeVaultTenantSA] assert.True(t, ok) } + +func TestTenantSAParseConfig(t *testing.T) { + t.Parallel() + vts := VaultTenantSA{} + + config := make(map[string]interface{}) + + // empty config map + err := vts.parseConfig(config) + if !errors.Is(err, errConfigOptionMissing) { + t.Errorf("unexpected error (%T): %s", err, err) + } + + // fill default options (normally done in initVaultTokensKMS) + config["vaultAddress"] = "https://vault.bob.cluster.svc" + config["vaultAuthPath"] = "/v1/auth/kube-auth/login" + + // parsing with all required options + err = vts.parseConfig(config) + switch { + case err != nil: + t.Errorf("unexpected error: %s", err) + case vts.vaultConfig["VAULT_AUTH_MOUNT_PATH"] != "kube-auth": + t.Errorf("vaultAuthPath set to unexpected value: %s", vts.vaultConfig["VAULT_AUTH_MOUNT_PATH"]) + } + + // tenant "bob" uses a different auth mount path + bob := make(map[string]interface{}) + bob["vaultAuthPath"] = "/v1/auth/bobs-cluster/login" + err = vts.parseConfig(bob) + switch { + case err != nil: + t.Errorf("unexpected error: %s", err) + case vts.vaultConfig["VAULT_AUTH_MOUNT_PATH"] != "bobs-cluster": + t.Errorf("vaultAuthPath set to unexpected value: %s", vts.vaultConfig["VAULT_AUTH_MOUNT_PATH"]) + } + + // auth mount path can be passed like VAULT_AUTH_MOUNT_PATH too + bob["vaultAuthPath"] = "bobs-2nd-cluster" + err = vts.parseConfig(bob) + switch { + case err != nil: + t.Errorf("unexpected error: %s", err) + case vts.vaultConfig["VAULT_AUTH_MOUNT_PATH"] != "bobs-2nd-cluster": + t.Errorf("vaultAuthPath set to unexpected value: %s", vts.vaultConfig["VAULT_AUTH_MOUNT_PATH"]) + } +}