Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Hashicorp Vault KV engine V1 #4152

Merged
merged 1 commit into from
Jan 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Here is an overview of all new **experimental** features:

- **General**: Add a warning when KEDA run outside supported k8s versions ([#4130](https://github.com/kedacore/keda/issues/4130))
- **General**: Use (self-signed) certificates for all the communications (internals and externals) ([#3931](https://github.com/kedacore/keda/issues/3931))
- **Hashicorp Vault**: Add support to secrets backend version 1 ([#2645](https://github.com/kedacore/keda/issues/2645))
- **RabbitMQ Scaler**: Add TLS support ([#967](https://github.com/kedacore/keda/issues/967))
- **Redis Scalers**: Add support to Redis 7 ([#4052](https://github.com/kedacore/keda/issues/4052))
- **Selenium Grid Scaler**: Add 'platformName' to selenium-grid scaler metadata structure ([#4038](https://github.com/kedacore/keda/issues/4038))
Expand Down
4 changes: 4 additions & 0 deletions pkg/scaling/resolver/scale_resolvers.go
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,10 @@ func resolveVaultSecret(logger logr.Logger, data map[string]interface{}, key str
logger.Error(fmt.Errorf("key '%s' not found", key), "error trying to get key from Vault secret")
return ""
}
} else if vData, ok := data[key]; ok {
if s, ok := vData.(string); ok {
return s
}
}

logger.Error(fmt.Errorf("unable to convert Vault Data value"), "error trying to convert Data secret vaule")
Expand Down
87 changes: 60 additions & 27 deletions tests/secret-providers/hashicorp_vault/hashicorp_vault_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package hashicorp_vault_test
import (
"encoding/base64"
"fmt"
"strings"
"testing"

"github.com/joho/godotenv"
Expand Down Expand Up @@ -46,6 +47,7 @@ type templateData struct {
VaultNamespace string
ScaledObjectName string
TriggerAuthenticationName string
VaultSecretPath string
SecretName string
HashiCorpToken string
PostgreSQLStatefulSetName string
Expand Down Expand Up @@ -119,7 +121,7 @@ spec:
secrets:
- parameter: connection
key: connectionString
path: secret/data/keda
path: {{.VaultSecretPath}}
`

scaledObjectTemplate = `
Expand Down Expand Up @@ -266,39 +268,63 @@ spec:
)

func TestPostreSQLScaler(t *testing.T) {
// Create kubernetes resources for PostgreSQL server
kc := GetKubernetesClient(t)
data, postgreSQLtemplates := getPostgreSQLTemplateData()
tests := []struct {
name string
vaultEngineVersion uint
vaultSecretPath string
}{
{
name: "vault kv engine v1",
vaultEngineVersion: 1,
vaultSecretPath: "secret/keda",
},
{
name: "vault kv engine v2",
vaultEngineVersion: 2,
vaultSecretPath: "secret/data/keda",
},
}

CreateKubernetesResources(t, kc, testNamespace, data, postgreSQLtemplates)
hashiCorpToken := setupHashiCorpVault(t, kc)
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
// Create kubernetes resources for PostgreSQL server
kc := GetKubernetesClient(t)
data, postgreSQLtemplates := getPostgreSQLTemplateData()

assert.True(t, WaitForStatefulsetReplicaReadyCount(t, kc, postgreSQLStatefulSetName, testNamespace, 1, 60, 3),
"replica count should be %d after 3 minutes", 1)
CreateKubernetesResources(t, kc, testNamespace, data, postgreSQLtemplates)
hashiCorpToken := setupHashiCorpVault(t, kc, test.vaultEngineVersion)

createTableSQL := "CREATE TABLE task_instance (id serial PRIMARY KEY,state VARCHAR(10));"
ok, out, errOut, err := WaitForSuccessfulExecCommandOnSpecificPod(t, postgresqlPodName, testNamespace,
fmt.Sprintf("psql -U %s -d %s -c \"%s\"", postgreSQLUsername, postgreSQLDatabase, createTableSQL), 60, 3)
assert.True(t, ok, "executing a command on PostreSQL Pod should work; Output: %s, ErrorOutput: %s, Error: %s", out, errOut, err)
assert.True(t, WaitForStatefulsetReplicaReadyCount(t, kc, postgreSQLStatefulSetName, testNamespace, 1, 60, 3),
"replica count should be %d after 3 minutes", 1)

// Create kubernetes resources for testing
data, templates := getTemplateData()
data.HashiCorpToken = RemoveANSI(hashiCorpToken)
KubectlApplyMultipleWithTemplate(t, data, templates)
assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3),
"replica count should be %d after 3 minutes", minReplicaCount)
createTableSQL := "CREATE TABLE task_instance (id serial PRIMARY KEY,state VARCHAR(10));"
psqlCreateTableCmd := fmt.Sprintf("psql -U %s -d %s -c \"%s\"", postgreSQLUsername, postgreSQLDatabase, createTableSQL)

ok, out, errOut, err := WaitForSuccessfulExecCommandOnSpecificPod(t, postgresqlPodName, testNamespace, psqlCreateTableCmd, 60, 3)
assert.True(t, ok, "executing a command on PostreSQL Pod should work; Output: %s, ErrorOutput: %s, Error: %s", out, errOut, err)

// Create kubernetes resources for testing
data, templates := getTemplateData()
data.HashiCorpToken = RemoveANSI(hashiCorpToken)
data.VaultSecretPath = test.vaultSecretPath

testActivation(t, kc, data)
testScaleOut(t, kc, data)
testScaleIn(t, kc)
KubectlApplyMultipleWithTemplate(t, data, templates)
assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3),
"replica count should be %d after 3 minutes", minReplicaCount)

// cleanup
KubectlDeleteMultipleWithTemplate(t, data, templates)
cleanupHashiCorpVault(t, kc)
DeleteKubernetesResources(t, kc, testNamespace, data, postgreSQLtemplates)
testActivation(t, kc, data)
testScaleOut(t, kc, data)
testScaleIn(t, kc)

// cleanup
KubectlDeleteMultipleWithTemplate(t, data, templates)
cleanupHashiCorpVault(t, kc)
DeleteKubernetesResources(t, kc, testNamespace, data, postgreSQLtemplates)
})
}
}

func setupHashiCorpVault(t *testing.T, kc *kubernetes.Clientset) string {
func setupHashiCorpVault(t *testing.T, kc *kubernetes.Clientset, kvVersion uint) string {
CreateNamespace(t, kc, vaultNamespace)

_, err := ExecuteCommand("helm repo add hashicorp https://helm.releases.hashicorp.com")
Expand All @@ -307,7 +333,14 @@ func setupHashiCorpVault(t *testing.T, kc *kubernetes.Clientset) string {
_, err = ExecuteCommand("helm repo update")
assert.NoErrorf(t, err, "cannot update repos - %s", err)

_, err = ExecuteCommand(fmt.Sprintf(`helm upgrade --install --set server.dev.enabled=true --namespace %s --wait vault hashicorp/vault`, vaultNamespace))
var helmValues strings.Builder
helmValues.WriteString("--set server.dev.enabled=true")

if kvVersion == 1 {
helmValues.WriteString(" --set server.extraArgs=-dev-kv-v1")
}

_, err = ExecuteCommand(fmt.Sprintf(`helm upgrade --install %s --namespace %s --wait vault hashicorp/vault`, helmValues.String(), vaultNamespace))
assert.NoErrorf(t, err, "cannot install hashicorp vault - %s", err)

podName := "vault-0"
Expand Down