Skip to content

Commit

Permalink
Test against Vault Enterprise (#11)
Browse files Browse the repository at this point in the history
Test against Vault Enterprise

We run the tests again but overwrite the `vault:dev` image with the
Enterprise image and ensure that the license is loaded.
  • Loading branch information
Christopher Swenson authored Jul 19, 2022
1 parent aab96f5 commit dee9534
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 7 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ jobs:
fail-fast: false
matrix:
kind-k8s-version: [1.21.12, 1.22.9, 1.23.6, 1.24.1]
enterprise: ["", "-ent"]
name: Integration test ${{ matrix.enterprise }} kind ${{ matrix.kind-k8s-version }}
steps:
- uses: actions/checkout@v2
- name: Create K8s Kind Cluster
Expand All @@ -79,7 +81,9 @@ jobs:
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- run: make setup-integration-test
- env:
VAULT_LICENSE_CI: ${{ secrets.VAULT_LICENSE_CI }}
run: make setup-integration-test${{ matrix.enterprise }}
- env:
INTEGRATION_TESTS: true
run: make integration-test TESTARGS="-v"
run: make integration-test TESTARGS="-v"
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Unreleased

* Test against Vault Enterprise [[GH-11](https://github.com/hashicorp/vault-plugin-secrets-kubernetes/pull/11)]

## 0.1.1 (May 26th, 2022)

### Changes
Expand Down
33 changes: 30 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ KIND_K8S_VERSION?=v1.24.1
PKG=github.com/hashicorp/vault-plugin-secrets-kubernetes
LDFLAGS?="-X '$(PKG).WALRollbackMinAge=10s'"

RUNNER_TEMP ?= $(TMPDIR)

.PHONY: default
default: dev

Expand Down Expand Up @@ -48,14 +50,28 @@ delete-kind:

.PHONY: vault-image
vault-image:
GOOS=linux GOARCH=amd64 make dev
GOOS=linux make dev
docker build -f integrationtest/vault/Dockerfile bin/ --tag=hashicorp/vault:dev

.PHONY: vault-image-ent
vault-image-ent:
GOOS=linux make dev
docker build -f integrationtest/vault/Dockerfile --target enterprise bin/ --tag=hashicorp/vault:dev

# Create Vault inside the cluster with a locally-built version of kubernetes secrets.
.PHONY: setup-integration-test
setup-integration-test: teardown-integration-test vault-image
.PHONY: setup-integration-test-common
setup-integration-test-common: SET_LICENSE=$(if $(VAULT_LICENSE_CI),--set server.enterpriseLicense.secretName=vault-license)
setup-integration-test-common: teardown-integration-test
kind --name ${KIND_CLUSTER_NAME} load docker-image hashicorp/vault:dev
kubectl create namespace test

# don't log the license
printenv VAULT_LICENSE_CI > $(RUNNER_TEMP)/vault-license.txt || true
if [ -s $(RUNNER_TEMP)/vault-license.txt ]; then \
kubectl -n test create secret generic vault-license --from-file license=$(RUNNER_TEMP)/vault-license.txt; \
rm -rf $(RUNNER_TEMP)/vault-license.txt; \
fi

helm install vault vault --repo https://helm.releases.hashicorp.com --version=0.19.0 \
--wait --timeout=5m \
--namespace=test \
Expand All @@ -64,6 +80,7 @@ setup-integration-test: teardown-integration-test vault-image
--set server.image.tag=dev \
--set server.image.pullPolicy=Never \
--set injector.enabled=false \
$(SET_LICENSE) \
--set server.extraArgs="-dev-plugin-dir=/vault/plugin_directory"
kubectl patch --namespace=test statefulset vault --patch-file integrationtest/vault/hostPortPatch.yaml
kubectl apply --namespace=test -f integrationtest/vault/testRoles.yaml
Expand All @@ -73,6 +90,16 @@ setup-integration-test: teardown-integration-test vault-image
kubectl delete --namespace=test pod vault-0
kubectl wait --namespace=test --for=condition=Ready --timeout=5m pod -l app.kubernetes.io/name=vault

.PHONY: setup-integration-test
setup-integration-test: vault-image setup-integration-test-common

.PHONY: setup-integration-test-ent
setup-integration-test-ent: check-license vault-image-ent setup-integration-test-common

.PHONY: check-license
check-license:
(printenv VAULT_LICENSE_CI > /dev/null) || (echo "VAULT_LICENSE_CI must be set"; exit 1)

.PHONY: teardown-integration-test
teardown-integration-test:
helm uninstall vault --namespace=test || true
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ require (
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/go-uuid v1.0.2 // indirect
github.com/hashicorp/go-version v1.2.0 // indirect
github.com/hashicorp/go-version v1.2.0
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
Expand Down
8 changes: 8 additions & 0 deletions integrationtest/creds_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ func TestCreds_ttl(t *testing.T) {

path, umount := mountHelper(t, client)
defer umount()
client, delNamespace := namespaceHelper(t, client)
defer delNamespace()

// create default config
_, err = client.Logical().Write(path+"/config", map[string]interface{}{})
Expand Down Expand Up @@ -129,6 +131,8 @@ func TestCreds_service_account_name(t *testing.T) {

path, umount := mountHelper(t, client)
defer umount()
client, delNamespace := namespaceHelper(t, client)
defer delNamespace()

// create default config
_, err = client.Logical().Write(path+"/config", map[string]interface{}{})
Expand Down Expand Up @@ -196,6 +200,8 @@ func TestCreds_kubernetes_role_name(t *testing.T) {

path, umount := mountHelper(t, client)
defer umount()
client, delNamespace := namespaceHelper(t, client)
defer delNamespace()

// create default config
_, err = client.Logical().Write(path+"/config", map[string]interface{}{})
Expand Down Expand Up @@ -276,6 +282,8 @@ func TestCreds_generated_role_rules(t *testing.T) {

path, umount := mountHelper(t, client)
defer umount()
client, delNamespace := namespaceHelper(t, client)
defer delNamespace()

// create default config
_, err = client.Logical().Write(path+"/config", map[string]interface{}{})
Expand Down
74 changes: 74 additions & 0 deletions integrationtest/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ func TestConfig(t *testing.T) {

path, umount := mountHelper(t, client)
defer umount()
client, delNamespace := namespaceHelper(t, client)
defer delNamespace()

// create
_, err = client.Logical().Write(path+"/config", map[string]interface{}{
Expand Down Expand Up @@ -126,6 +128,8 @@ func TestRole(t *testing.T) {

path, umount := mountHelper(t, client)
defer umount()
client, delNamespace := namespaceHelper(t, client)
defer delNamespace()

// create default config
_, err = client.Logical().Write(path+"/config", map[string]interface{}{})
Expand Down Expand Up @@ -191,6 +195,42 @@ func TestRole(t *testing.T) {
assert.Nil(t, result)
}

func isEnterprise(client *api.Client) bool {
req := client.NewRequest("GET", "/v1/sys/license/status")
resp, err := client.RawRequest(req)
if err != nil {
return false
}
return resp.StatusCode == 200
}

func createNamespace(client *api.Client, namespace string) error {
req := client.NewRequest("PUT", "/v1/sys/namespaces/"+namespace)
resp, err := client.RawRequest(req)
if err != nil {
return err
}

if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("error creating namespace. Server returned status %d %s", resp.StatusCode, resp.Status)
}
return nil
}

func deleteNamespace(client *api.Client, namespace string) error {
req := client.NewRequest("DELETE", "/v1/sys/namespaces/"+namespace)
resp, err := client.RawRequest(req)
if err != nil {
return err
}

if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("error creating namespace. Server returned status %d %s", resp.StatusCode, resp.Status)
}
return nil
}

// mountHelper creates the kubernetes mount.
func mountHelper(t *testing.T, client *api.Client) (string, func()) {
t.Helper()

Expand All @@ -211,6 +251,40 @@ func mountHelper(t *testing.T, client *api.Client) (string, func()) {
}
}

// namespaceHelper creates a Vault Enterprise namespace and returns a client with the namespace changed to it.
func namespaceHelper(t *testing.T, client *api.Client) (*api.Client, func()) {
t.Helper()

var err error
namespace := ""
newClient := client

if isEnterprise(client) {
namespace := randomWithPrefix("somenamespace")
if err != nil {
t.Fatal(err)
}
err = createNamespace(client, namespace)
if err != nil {
t.Fatal(err)
}
newClient, err := client.Clone()
if err != nil {
t.Fatal(err)
}
newClient.SetNamespace(namespace)
}

return newClient, func() {
if namespace != "" {
err = deleteNamespace(client, namespace)
if err != nil {
t.Fatal(err)
}
}
}
}

const sampleRules = `rules:
- apiGroups: [""]
resources: ["pods"]
Expand Down
6 changes: 6 additions & 0 deletions integrationtest/vault/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
FROM docker.mirror.hashicorp.services/hashicorp/vault-enterprise:1.10.3-ent as enterprise

# Don't use `kubernetes` as plugin name to ensure we don't silently fall back to
# the built-in kubernetes secrets plugin if something goes wrong.
COPY --chown=vault:vault vault-plugin-secrets-kubernetes /vault/plugin_directory/kubernetes-dev

FROM docker.mirror.hashicorp.services/hashicorp/vault:1.10.3

# Don't use `kubernetes` as plugin name to ensure we don't silently fall back to
Expand Down
5 changes: 4 additions & 1 deletion integrationtest/wal_rollback_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ func TestCreds_wal_rollback(t *testing.T) {
}

// Pick up VAULT_ADDR and VAULT_TOKEN from env vars
client, err := api.NewClient(nil)
baseClient, err := api.NewClient(nil)
if err != nil {
t.Fatal(err)
}

client, delNamespace := namespaceHelper(t, baseClient)
defer delNamespace()

t.Run("generated_role_rules", func(t *testing.T) {
t.Parallel()
mountPath, umount := mountHelper(t, client)
Expand Down

0 comments on commit dee9534

Please sign in to comment.