1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00
sap-jenkins-library/integration/integration_vault_test.go
Sven Merk a1988f6808
feat(whitesourceExecuteScan): GitHub issue creation + SARIF (#3535)
* Add GH issue creation + SARIF

* Code cleanup

* Fix fmt, add debug

* Code enhancements

* Fix

* Added debug info

* Rework UA log scan

* Fix code

* read UA version

* Fix nil reference

* Extraction

* Credentials

* Issue creation

* Error handling

* Fix issue creation

* query escape

* Query escape 2

* Revert

* Test avoid update

* HTTP client

* Add support for custom TLS certs

* Fix code

* Fix code 2

* Fix code 3

* Disable cert check

* Fix auth

* Remove implicit trust

* Skip verification

* Fix

* Fix client

* Fix HTTP auth

* Fix trusted certs

* Trim version

* Code

* Add token

* Added token handling to client

* Fix token

* Cleanup

* Fix token

* Token rework

* Fix code

* Kick out oauth client

* Kick out oauth client

* Transport wrapping

* Token

* Simplification

* Refactor

* Variation

* Check

* Fix

* Debug

* Switch client

* Variation

* Debug

* Switch to cert check

* Add debug

* Parse self

* Cleanup

* Update resources/metadata/whitesourceExecuteScan.yaml

* Add debug

* Expose subjects

* Patch

* Debug

* Debug2

* Debug3

* Fix logging response body

* Cleanup

* Cleanup

* Fix request body logging

* Cleanup import

* Fix import cycle

* Cleanup

* Fix fmt

* Fix NopCloser reference

* Regenerate

* Reintroduce

* Fix test

* Fix tests

* Correction

* Fix error

* Code fix

* Fix tests

* Add tests

* Fix code climate issues

* Code climate

* Code climate again

* Code climate again

* Fix fmt

* Fix fmt 2

Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com>
2022-02-23 09:30:19 +01:00

326 lines
9.4 KiB
Go

//go:build integration
// +build integration
// can be execute with go test -tags=integration ./integration/...
package main
import (
"context"
"encoding/json"
"fmt"
"testing"
"time"
"github.com/SAP/jenkins-library/pkg/vault"
"github.com/hashicorp/vault/api"
"github.com/stretchr/testify/assert"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)
type SecretData = map[string]interface{}
func TestGetVaultSecret(t *testing.T) {
t.Parallel()
ctx := context.Background()
const testToken = "vault-token"
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
AlwaysPullImage: true,
Image: "vault:1.4.3",
ExposedPorts: []string{"8200/tcp"},
Env: map[string]string{"VAULT_DEV_ROOT_TOKEN_ID": testToken},
WaitingFor: wait.ForLog("Vault server started!").WithStartupTimeout(20 * time.Second)},
Started: true,
}
vaultContainer, err := testcontainers.GenericContainer(ctx, req)
assert.NoError(t, err)
defer vaultContainer.Terminate(ctx)
ip, err := vaultContainer.Host(ctx)
assert.NoError(t, err)
port, err := vaultContainer.MappedPort(ctx, "8200")
host := fmt.Sprintf("http://%s:%s", ip, port.Port())
config := &vault.Config{Config: &api.Config{Address: host}}
// setup vault for testing
secretData := SecretData{
"key1": "value1",
"key2": "value2",
}
setupVault(t, config, testToken, secretData)
client, err := vault.NewClient(config, testToken)
assert.NoError(t, err)
secret, err := client.GetKvSecret("secret/test")
assert.NoError(t, err)
assert.Equal(t, "value1", secret["key1"])
assert.Equal(t, "value2", secret["key2"])
secret, err = client.GetKvSecret("kv/test")
assert.NoError(t, err)
assert.Equal(t, "value1", secret["key1"])
assert.Equal(t, "value2", secret["key2"])
}
func TestWriteVaultSecret(t *testing.T) {
t.Parallel()
ctx := context.Background()
const testToken = "vault-token"
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
AlwaysPullImage: true,
Image: "vault:1.4.3",
ExposedPorts: []string{"8200/tcp"},
Env: map[string]string{"VAULT_DEV_ROOT_TOKEN_ID": testToken},
WaitingFor: wait.ForLog("Vault server started!").WithStartupTimeout(20 * time.Second)},
Started: true,
}
vaultContainer, err := testcontainers.GenericContainer(ctx, req)
assert.NoError(t, err)
defer vaultContainer.Terminate(ctx)
ip, err := vaultContainer.Host(ctx)
assert.NoError(t, err)
port, err := vaultContainer.MappedPort(ctx, "8200")
host := fmt.Sprintf("http://%s:%s", ip, port.Port())
config := &vault.Config{Config: &api.Config{Address: host}}
// setup vault for testing
secretData := map[string]string{
"key1": "value1",
"key2": "value2",
}
client, err := vault.NewClient(config, testToken)
assert.NoError(t, err)
err = client.WriteKvSecret("secret/test", secretData)
assert.NoError(t, err)
secret, err := client.GetKvSecret("secret/test")
assert.NoError(t, err)
assert.Equal(t, "value1", secret["key1"])
assert.Equal(t, "value2", secret["key2"])
// enabling KV engine 1
vaultClient, err := api.NewClient(config.Config)
assert.NoError(t, err)
vaultClient.SetToken(testToken)
_, err = vaultClient.Logical().Write("sys/mounts/kv", SecretData{
"path": "kv",
"type": "kv",
"options": SecretData{
"version": "1",
},
})
assert.NoError(t, err)
err = client.WriteKvSecret("secret/test1", secretData)
assert.NoError(t, err)
secret, err = client.GetKvSecret("secret/test1")
assert.NoError(t, err)
assert.Equal(t, "value1", secret["key1"])
assert.Equal(t, "value2", secret["key2"])
}
func TestVaultAppRole(t *testing.T) {
t.Parallel()
ctx := context.Background()
const testToken = "vault-token"
const appRolePath = "auth/approle/role/test"
const appRoleName = "test"
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
AlwaysPullImage: true,
Image: "vault:1.4.3",
ExposedPorts: []string{"8200/tcp"},
Env: map[string]string{"VAULT_DEV_ROOT_TOKEN_ID": testToken},
WaitingFor: wait.ForLog("Vault server started!").WithStartupTimeout(20 * time.Second)},
Started: true,
}
vaultContainer, err := testcontainers.GenericContainer(ctx, req)
assert.NoError(t, err)
defer vaultContainer.Terminate(ctx)
ip, err := vaultContainer.Host(ctx)
assert.NoError(t, err)
port, err := vaultContainer.MappedPort(ctx, "8200")
host := fmt.Sprintf("http://%s:%s", ip, port.Port())
config := &vault.Config{Config: &api.Config{Address: host}}
secretIDMetadata := map[string]interface{}{
"field1": "value1",
}
roleID, secretID := setupVaultAppRole(t, config, testToken, appRolePath, secretIDMetadata)
t.Run("Test Vault AppRole login", func(t *testing.T) {
client, err := vault.NewClientWithAppRole(config, roleID, secretID)
assert.NoError(t, err)
secret, err := client.GetSecret("auth/token/lookup-self")
meta := secret.Data["meta"].(SecretData)
assert.Equal(t, meta["field1"], "value1")
assert.Equal(t, meta["role_name"], "test")
assert.NoError(t, err)
})
t.Run("Test Vault AppRoleTTL Fetch", func(t *testing.T) {
client, err := vault.NewClient(config, testToken)
assert.NoError(t, err)
ttl, err := client.GetAppRoleSecretIDTtl(secretID, appRoleName)
assert.NoError(t, err)
assert.Equal(t, time.Duration(90*24*time.Hour), ttl.Round(time.Hour))
})
t.Run("Test Vault AppRole Rotation", func(t *testing.T) {
client, err := vault.NewClient(config, testToken)
assert.NoError(t, err)
newSecretID, err := client.GenerateNewAppRoleSecret(secretID, appRoleName)
assert.NoError(t, err)
assert.NotEmpty(t, newSecretID)
assert.NotEqual(t, secretID, newSecretID)
// verify metadata is not broken
client, err = vault.NewClientWithAppRole(config, roleID, newSecretID)
assert.NoError(t, err)
secret, err := client.GetSecret("auth/token/lookup-self")
meta := secret.Data["meta"].(SecretData)
assert.Equal(t, meta["field1"], "value1")
assert.Equal(t, meta["role_name"], "test")
assert.NoError(t, err)
})
t.Run("Test Fetching RoleName from vault", func(t *testing.T) {
client, err := vault.NewClientWithAppRole(config, roleID, secretID)
assert.NoError(t, err)
fetchedRoleName, err := client.GetAppRoleName()
assert.NoError(t, err)
assert.Equal(t, appRoleName, fetchedRoleName)
})
}
func TestTokenRevocation(t *testing.T) {
t.Parallel()
ctx := context.Background()
const testToken = "vault-token"
const appRolePath = "auth/approle/role/test"
const appRoleName = "test"
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
AlwaysPullImage: true,
Image: "vault:1.4.3",
ExposedPorts: []string{"8200/tcp"},
Env: map[string]string{"VAULT_DEV_ROOT_TOKEN_ID": testToken},
WaitingFor: wait.ForLog("Vault server started!").WithStartupTimeout(20 * time.Second)},
Started: true,
}
vaultContainer, err := testcontainers.GenericContainer(ctx, req)
assert.NoError(t, err)
defer vaultContainer.Terminate(ctx)
ip, err := vaultContainer.Host(ctx)
assert.NoError(t, err)
port, err := vaultContainer.MappedPort(ctx, "8200")
host := fmt.Sprintf("http://%s:%s", ip, port.Port())
config := &vault.Config{Config: &api.Config{Address: host}}
secretIDMetadata := map[string]interface{}{
"field1": "value1",
}
roleID, secretID := setupVaultAppRole(t, config, testToken, appRolePath, secretIDMetadata)
t.Run("Test Revocation works", func(t *testing.T) {
client, err := vault.NewClientWithAppRole(config, roleID, secretID)
assert.NoError(t, err)
secret, err := client.GetSecret("auth/token/lookup-self")
meta := secret.Data["meta"].(SecretData)
assert.Equal(t, meta["field1"], "value1")
assert.Equal(t, meta["role_name"], "test")
assert.NoError(t, err)
err = client.RevokeToken()
assert.NoError(t, err)
_, err = client.GetSecret("auth/token/lookup-self")
assert.Error(t, err)
})
}
func setupVaultAppRole(t *testing.T, config *vault.Config, token, appRolePath string, metadata map[string]interface{}) (string, string) {
t.Helper()
client, err := api.NewClient(config.Config)
assert.NoError(t, err)
client.SetToken(token)
lClient := client.Logical()
_, err = lClient.Write("sys/auth/approle", SecretData{
"type": "approle",
"config": map[string]interface{}{
"default_lease_ttl": "7776000s",
"max_lease_ttl": "7776000s",
},
})
assert.NoError(t, err)
_, err = lClient.Write("auth/approle/role/test", SecretData{
"secret_id_ttl": 7776000,
})
assert.NoError(t, err)
metadataJson, err := json.Marshal(metadata)
assert.NoError(t, err)
res, err := lClient.Write("auth/approle/role/test/secret-id", SecretData{
"metadata": string(metadataJson),
})
assert.NoError(t, err)
secretID := res.Data["secret_id"]
res, err = lClient.Read("auth/approle/role/test/role-id")
assert.NoError(t, err)
roleID := res.Data["role_id"]
return roleID.(string), secretID.(string)
}
func setupVault(t *testing.T, config *vault.Config, token string, secret SecretData) {
t.Helper()
client, err := api.NewClient(config.Config)
assert.NoError(t, err)
client.SetToken(token)
_, err = client.Logical().Write("secret/data/test", SecretData{"data": secret})
assert.NoError(t, err)
// enabling KV engine 1
_, err = client.Logical().Write("sys/mounts/kv", SecretData{
"path": "kv",
"type": "kv",
"options": SecretData{
"version": "1",
},
})
assert.NoError(t, err)
_, err = client.Logical().Write("kv/test", secret)
assert.NoError(t, err)
}