Skip to content

Commit a8b484a

Browse files
committed
add e2e test
Signed-off-by: Bojan Zelic <[email protected]>
1 parent 95e7c47 commit a8b484a

File tree

6 files changed

+80
-30
lines changed

6 files changed

+80
-30
lines changed

config/e2e/kustomization.yaml

+7-1
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@ resources:
99
apiVersion: kustomize.config.k8s.io/v1beta1
1010
kind: Kustomization
1111
patches:
12-
- path: patch_operator.yml
12+
- path: patch_operator.yaml
1313
target:
1414
group: apps
1515
kind: Deployment
1616
name: keda-operator
1717
version: v1
18+
- path: patch_rbac.yaml
19+
target:
20+
group: rbac.authorization.k8s.io
21+
kind: ClusterRole
22+
name: keda-operator
23+
version: v1
File renamed without changes.

config/e2e/patch_rbac.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
- op: add
2+
path: /rules/-
3+
value:
4+
apiGroups:
5+
- ""
6+
resources:
7+
- serviceaccounts/token
8+
verbs:
9+
- create

pkg/scaling/resolver/hashicorpvault_handler.go

+8-16
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,19 @@ package resolver
1919
import (
2020
"context"
2121
"encoding/json"
22-
"errors"
2322
"fmt"
2423
"os"
2524
"strings"
2625

27-
apierrors "k8s.io/apimachinery/pkg/api/errors"
28-
2926
"github.com/go-logr/logr"
3027
vaultapi "github.com/hashicorp/vault/api"
31-
"k8s.io/apimachinery/pkg/types"
32-
33-
kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1"
28+
"github.com/pkg/errors"
3429
authenticationv1 "k8s.io/api/authentication/v1"
35-
3630
corev1 "k8s.io/api/core/v1"
31+
"k8s.io/apimachinery/pkg/types"
3732
"sigs.k8s.io/controller-runtime/pkg/client"
33+
34+
kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1"
3835
)
3936

4037
// HashicorpVaultHandler is specification of Hashi Corp Vault
@@ -141,19 +138,15 @@ func (vh *HashicorpVaultHandler) token(client *vaultapi.Client) (string, error)
141138
secret := &corev1.Secret{}
142139

143140
if err = vh.k8sClient.Get(context.Background(), saName, sa); err != nil {
144-
if apierrors.IsNotFound(err) {
145-
return token, errors.New(fmt.Sprintf("Failed to retreive service account name: %s namespace: %s", saName.Name, saName.Namespace))
146-
}
141+
return token, errors.Wrap(err, fmt.Sprintf("Failed to retrieve service account name: %s namespace: %s", saName.Name, saName.Namespace))
147142
}
148143

149144
if len(sa.Secrets) > 0 {
150-
//using legacy service account secrets
145+
// using legacy service account secrets
151146
secretName := types.NamespacedName{Name: sa.Secrets[0].Name, Namespace: vh.namespace}
152147

153148
if err = vh.k8sClient.Get(context.Background(), secretName, secret); err != nil {
154-
if apierrors.IsNotFound(err) {
155-
return token, errors.New(fmt.Sprintf("Failed to retreive secret for service account name: %s namespace: %s", secretName.Name, secretName.Namespace))
156-
}
149+
return token, errors.Wrap(err, fmt.Sprintf("Failed to retrieve secret for service account name: %s namespace: %s", secretName.Name, secretName.Namespace))
157150
}
158151

159152
jwt = secret.Data["token"]
@@ -171,12 +164,11 @@ func (vh *HashicorpVaultHandler) token(client *vaultapi.Client) (string, error)
171164
}
172165

173166
if err := vh.k8sClient.SubResource("token").Create(context.Background(), sa, tokenRequest); err != nil {
174-
return token, errors.New(fmt.Sprintf("Failed to create token for service account name: %s namespace: %s", saName.Name, saName.Namespace))
167+
return token, errors.Wrap(err, fmt.Sprintf("Failed to create token for service account name: %s namespace: %s", saName.Name, saName.Namespace))
175168
}
176169

177170
jwt = []byte(tokenRequest.Status.Token)
178171
}
179-
180172
} else if len(vh.vault.Credential.ServiceAccount) != 0 {
181173
// Get the JWT from POD
182174
jwt, err = os.ReadFile(vh.vault.Credential.ServiceAccount)

pkg/scaling/resolver/hashicorpvault_handler_test.go

+2-7
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ import (
2929
vaultapi "github.com/hashicorp/vault/api"
3030
"github.com/stretchr/testify/assert"
3131
"go.uber.org/mock/gomock"
32+
authenticationv1 "k8s.io/api/authentication/v1"
3233
corev1 "k8s.io/api/core/v1"
3334
"k8s.io/apimachinery/pkg/types"
35+
"sigs.k8s.io/controller-runtime/pkg/client"
3436
logf "sigs.k8s.io/controller-runtime/pkg/log"
3537

3638
kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1"
3739
"github.com/kedacore/keda/v2/pkg/mock/mock_client"
38-
authenticationv1 "k8s.io/api/authentication/v1"
39-
"sigs.k8s.io/controller-runtime/pkg/client"
4040
)
4141

4242
const (
@@ -78,11 +78,6 @@ var (
7878
"test": kedaSecretValue,
7979
"array": []string{kedaSecretValue},
8080
}
81-
kubernetesAuthDataKeda = map[string]interface{}{
82-
"auth": map[string]interface{}{
83-
"client_token": vaultTestToken,
84-
},
85-
}
8681
)
8782

8883
type pkiRequestTestData struct {

tests/secret-providers/hashicorp_vault/hashicorp_vault_test.go

+54-6
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ type templateData struct {
7070
MonitoredAppName string
7171
PrometheusServerName string
7272
VaultPkiCommonName string
73+
VaultRole string
74+
VaultServiceAccountName string
7375
}
7476

7577
const (
@@ -128,9 +130,12 @@ metadata:
128130
spec:
129131
hashiCorpVault:
130132
address: http://vault.{{.VaultNamespace}}:8200
131-
authentication: token
133+
authentication: {{.HashiCorpAuthentication}}
134+
role: {{.VaultRole}}
135+
mount: kubernetes
132136
credential:
133137
token: {{.HashiCorpToken}}
138+
serviceAccountName: {{.VaultServiceAccountName}}
134139
secrets:
135140
- parameter: connection
136141
key: connectionString
@@ -413,6 +418,13 @@ spec:
413418
pkiPolicyTemplate = `path "pki*" {
414419
capabilities = [ "create", "read", "update", "delete", "list", "sudo" ]
415420
}`
421+
422+
secretReadPolicyTemplate = `path "secret/data/keda" {
423+
capabilities = ["read"]
424+
}
425+
path "secret/metadata/keda" {
426+
capabilities = ["read", "list"]
427+
}`
416428
)
417429

418430
func TestPkiSecretsEngine(t *testing.T) {
@@ -432,7 +444,7 @@ func TestPkiSecretsEngine(t *testing.T) {
432444
// Create kubernetes resources
433445
kc := GetKubernetesClient(t)
434446
useKubernetesAuth := test.authentication == "kubernetes"
435-
hashiCorpToken, promPkiData := setupHashiCorpVault(t, kc, 2, useKubernetesAuth, true)
447+
hashiCorpToken, promPkiData := setupHashiCorpVault(t, kc, 2, useKubernetesAuth, true, false)
436448
prometheus.Install(t, kc, prometheusServerName, testNamespace, promPkiData)
437449

438450
// Create kubernetes resources for testing
@@ -460,16 +472,29 @@ func TestSecretsEngine(t *testing.T) {
460472
name string
461473
vaultEngineVersion uint
462474
vaultSecretPath string
475+
useKubernetesAuth bool
476+
useDelegatesSAAuth bool
463477
}{
464478
{
465479
name: "vault kv engine v1",
466480
vaultEngineVersion: 1,
467481
vaultSecretPath: "secret/keda",
482+
useKubernetesAuth: false,
483+
useDelegatesSAAuth: false,
484+
},
485+
{
486+
name: "vault kv engine v2",
487+
vaultEngineVersion: 2,
488+
vaultSecretPath: "secret/data/keda",
489+
useKubernetesAuth: false,
490+
useDelegatesSAAuth: false,
468491
},
469492
{
470493
name: "vault kv engine v2",
471494
vaultEngineVersion: 2,
472495
vaultSecretPath: "secret/data/keda",
496+
useKubernetesAuth: true,
497+
useDelegatesSAAuth: true,
473498
},
474499
}
475500

@@ -480,7 +505,7 @@ func TestSecretsEngine(t *testing.T) {
480505
data, postgreSQLtemplates := getPostgreSQLTemplateData()
481506

482507
CreateKubernetesResources(t, kc, testNamespace, data, postgreSQLtemplates)
483-
hashiCorpToken, _ := setupHashiCorpVault(t, kc, test.vaultEngineVersion, false, false)
508+
hashiCorpToken, _ := setupHashiCorpVault(t, kc, test.vaultEngineVersion, test.useKubernetesAuth, false, test.useDelegatesSAAuth)
484509

485510
assert.True(t, WaitForStatefulsetReplicaReadyCount(t, kc, postgreSQLStatefulSetName, testNamespace, 1, 60, 3),
486511
"replica count should be %d after 3 minutes", 1)
@@ -493,8 +518,19 @@ func TestSecretsEngine(t *testing.T) {
493518

494519
// Create kubernetes resources for testing
495520
data, templates := getTemplateData()
496-
data.HashiCorpToken = RemoveANSI(hashiCorpToken)
497521
data.VaultSecretPath = test.vaultSecretPath
522+
data.VaultRole = "keda"
523+
if test.useKubernetesAuth {
524+
data.HashiCorpAuthentication = "kubernetes"
525+
} else {
526+
data.HashiCorpAuthentication = "token"
527+
data.HashiCorpToken = RemoveANSI(hashiCorpToken)
528+
}
529+
530+
if test.useDelegatesSAAuth {
531+
data.VaultRole = "vault-delegated-sa"
532+
data.VaultServiceAccountName = "default"
533+
}
498534

499535
KubectlApplyMultipleWithTemplate(t, data, templates)
500536
assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3),
@@ -548,7 +584,7 @@ func setupHashiCorpVaultPki(t *testing.T, podName string, nameSpace string) *pro
548584
return &pkiData
549585
}
550586

551-
func setupHashiCorpVault(t *testing.T, kc *kubernetes.Clientset, kvVersion uint, useKubernetesAuth, pki bool) (string, *prometheus.VaultPkiData) {
587+
func setupHashiCorpVault(t *testing.T, kc *kubernetes.Clientset, kvVersion uint, useKubernetesAuth, pki, delegatedAuth bool) (string, *prometheus.VaultPkiData) {
552588
CreateNamespace(t, kc, vaultNamespace)
553589

554590
_, err := ExecuteCommand("helm repo add hashicorp https://helm.releases.hashicorp.com")
@@ -572,7 +608,7 @@ func setupHashiCorpVault(t *testing.T, kc *kubernetes.Clientset, kvVersion uint,
572608
// Enable Kubernetes auth
573609
if useKubernetesAuth {
574610
if pki {
575-
remoteFile := "/tmp/policy.hcl"
611+
remoteFile := "/tmp/pki_policy.hcl"
576612
KubectlCopyToPod(t, pkiPolicyTemplate, remoteFile, podName, vaultNamespace)
577613
assert.NoErrorf(t, err, "cannot create policy file in hashicorp vault - %s", err)
578614
_, _, err = ExecCommandOnSpecificPod(t, podName, vaultNamespace, fmt.Sprintf("vault policy write pkiPolicy %s", remoteFile))
@@ -584,9 +620,21 @@ func setupHashiCorpVault(t *testing.T, kc *kubernetes.Clientset, kvVersion uint,
584620
assert.NoErrorf(t, err, "cannot set kubernetes host in hashicorp vault - %s", err)
585621
_, _, err = ExecCommandOnSpecificPod(t, podName, vaultNamespace, "vault write auth/kubernetes/role/keda bound_service_account_names=keda-operator bound_service_account_namespaces=keda policies=pkiPolicy ttl=1h")
586622
assert.NoErrorf(t, err, "cannot cerate keda role in hashicorp vault - %s", err)
623+
if delegatedAuth {
624+
remoteFile := "/tmp/secret_read_policy.hcl"
625+
KubectlCopyToPod(t, secretReadPolicyTemplate, remoteFile, podName, vaultNamespace)
626+
assert.NoErrorf(t, err, "cannot create policy file in hashicorp vault - %s", err)
627+
_, _, err = ExecCommandOnSpecificPod(t, podName, vaultNamespace, fmt.Sprintf("vault policy write secretReadPolicy %s", remoteFile))
628+
assert.NoErrorf(t, err, "cannot create policy in hashicorp vault - %s", err)
629+
630+
_, _, err = ExecCommandOnSpecificPod(t, podName, vaultNamespace, fmt.Sprintf("vault write auth/kubernetes/role/vault-delegated-sa bound_service_account_names=default bound_service_account_namespaces=%s policies=secretReadPolicy ttl=1h", testNamespace))
631+
assert.NoErrorf(t, err, "cannot cerate keda role in hashicorp vault - %s", err)
632+
}
587633
}
634+
588635
// Create kv secret
589636
if !pki {
637+
t.Logf("added secret")
590638
_, _, err = ExecCommandOnSpecificPod(t, podName, vaultNamespace, fmt.Sprintf("vault kv put secret/keda connectionString=%s", postgreSQLConnectionString))
591639
assert.NoErrorf(t, err, "cannot put connection string in hashicorp vault - %s", err)
592640
}

0 commit comments

Comments
 (0)