github.com/tommi2day/gomodules@v1.13.2-0.20240423190010-b7d55d252a27/pwlib/vault_test.go (about)

     1  package pwlib
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path"
     7  	"testing"
     8  
     9  	"github.com/tommi2day/gomodules/common"
    10  
    11  	"github.com/tommi2day/gomodules/test"
    12  
    13  	vault "github.com/hashicorp/vault/api"
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestVault(t *testing.T) {
    19  	var vc *vault.Client
    20  	var kvs *vault.KVSecret
    21  	var vs *vault.Secret
    22  	if os.Getenv("SKIP_Vault") != "" {
    23  		t.Skip("Skipping Vault testing in CI environment")
    24  	}
    25  	vaultContainer, err := prepareVaultContainer()
    26  	require.NoErrorf(t, err, "Vault Server not available")
    27  	require.NotNil(t, vaultContainer, "Prepare failed")
    28  	defer common.DestroyDockerContainer(vaultContainer)
    29  
    30  	host, vaultPort := common.GetContainerHostAndPort(vaultContainer, "8200/tcp")
    31  	address := fmt.Sprintf("http://%s:%d", host, vaultPort)
    32  	_ = os.Unsetenv("VAULT_ADDR")
    33  	_ = os.Unsetenv("VAULT_TOKEN")
    34  	t.Run("Vault Connect direct", func(t *testing.T) {
    35  		t.Logf("Connect to vault using %s and token %s", address, rootToken)
    36  		vc, err = VaultConfig(address, rootToken)
    37  		// validate connect with lookup myself
    38  		secret, err := vc.Auth().Token().LookupSelf()
    39  		require.NoErrorf(t, err, "Token Lookup returned error: %v", err)
    40  		assert.NotNilf(t, secret, "Vault Token is nil")
    41  		vc.ClearToken()
    42  	})
    43  	t.Run("Vault Wrong Token", func(t *testing.T) {
    44  		t.Logf("Connect to vault using %s and token %s", address, "xxx")
    45  		vc, err = VaultConfig(address, "xxx")
    46  		// validate connect with lookup myself
    47  		secret, err := vc.Auth().Token().LookupSelf()
    48  		require.Error(t, err, "Test should fail")
    49  		assert.Nilf(t, secret, "Vault auth should not return")
    50  		vc.ClearToken()
    51  	})
    52  	t.Run("Vault Connect with Env", func(t *testing.T) {
    53  		t.Log("Connect to vault using env")
    54  		_ = os.Setenv("VAULT_ADDR", address)
    55  		_ = os.Setenv("VAULT_TOKEN", rootToken)
    56  		vc, err = VaultConfig("", "")
    57  		// validate connect with lookup myself
    58  		secret, err := vc.Auth().Token().LookupSelf()
    59  		require.NoErrorf(t, err, "Token Lookup returned error: %v", err)
    60  		assert.NotNilf(t, secret, "Vault auth should not return")
    61  		vc.ClearToken()
    62  		_ = os.Unsetenv("VAULT_ADDR")
    63  		_ = os.Unsetenv("VAULT_TOKEN")
    64  	})
    65  
    66  	vc, err = VaultConfig(address, rootToken)
    67  	// validate connect with lookup myself
    68  	secret, err := vc.Auth().Token().LookupSelf()
    69  	require.NoErrorf(t, err, "Connect returned error: %v", err)
    70  	assert.NotNilf(t, secret, "Vault auth should not return")
    71  	t.Run("Vault KV Write", func(t *testing.T) {
    72  		var vaultdata = map[string]interface{}{
    73  			"password": "Hashi123",
    74  		}
    75  		err = VaultKVWrite(vc, "secret", "test", vaultdata)
    76  		require.NoErrorf(t, err, "Write returned error: %v", err)
    77  	})
    78  	t.Run("Vault KV Wrong Path", func(t *testing.T) {
    79  		kvs, err = VaultKVRead(vc, "secret", "test-wrong")
    80  		require.Error(t, err, "Read should return an error")
    81  		require.Nilf(t, kvs, "Vault Secret should be nil")
    82  	})
    83  	t.Run("Vault KV Read", func(t *testing.T) {
    84  		kvs, err = VaultKVRead(vc, "secret", "test")
    85  		require.NoErrorf(t, err, "Read returned error: %v", err)
    86  		require.NotNilf(t, kvs, "Vault Secret is nil")
    87  		value, ok := kvs.Data["password"].(string)
    88  		require.True(t, ok, "Key password not found")
    89  		assert.Equalf(t, value, "Hashi123", "unexpected password value %q retrieved from vault", value)
    90  	})
    91  	t.Run("Vault logical Write", func(t *testing.T) {
    92  		var vaultdata = map[string]interface{}{
    93  			"data": map[string]interface{}{
    94  				"password": "Hashi345",
    95  			},
    96  		}
    97  		err = VaultWrite(vc, path.Join("secret", "data", "test2"), vaultdata)
    98  		require.NoErrorf(t, err, "Write returned error: %v", err)
    99  	})
   100  	t.Run("Vault List", func(t *testing.T) {
   101  		var vaultkeys []interface{}
   102  		vs, err = VaultList(vc, path.Join("secret", "metadata"))
   103  		require.NoErrorf(t, err, "List returned error: %v", err)
   104  		require.NotNilf(t, vs, "Vault Secret is nil")
   105  		vaultwarn := vs.Warnings
   106  		assert.Nil(t, vaultwarn, "Should have no warnings, but got %v", vaultwarn)
   107  		require.NotNil(t, vs.Data, "No Data returned")
   108  
   109  		vaultkeys = vs.Data["keys"].([]interface{})
   110  		require.NotNil(t, vaultkeys, "No Keys returned")
   111  		assert.Equalf(t, 2, len(vaultkeys), "Returned key count not as expected")
   112  		for i, k := range vaultkeys {
   113  			t.Logf("key returned %d:%s", i, k)
   114  		}
   115  	})
   116  	t.Run("Vault Logical Read", func(t *testing.T) {
   117  		var vaultdata map[string]interface{}
   118  		vs, err = VaultRead(vc, path.Join("secret", "data", "test2"))
   119  		require.NoErrorf(t, err, "Read returned error: %v", err)
   120  		require.NotNilf(t, vs, "Vault Secret is nil")
   121  		vaultwarn := vs.Warnings
   122  		assert.Nil(t, vaultwarn, "Should have no warnings, but got %v", vaultwarn)
   123  		require.NotNil(t, vs.Data, "No Data returned")
   124  		ok := false
   125  		value := ""
   126  		vaultdata = vs.Data["data"].(map[string]interface{})
   127  		value, ok = vaultdata["password"].(string)
   128  		require.True(t, ok, "Key password not found")
   129  		assert.Equalf(t, value, "Hashi345", "unexpected password value %q retrieved from vault", value)
   130  	})
   131  	t.Run("Vault GetPassword", func(t *testing.T) {
   132  		// need Env as config is here not exposed
   133  		_ = os.Setenv("VAULT_ADDR", address)
   134  		_ = os.Setenv("VAULT_TOKEN", rootToken)
   135  		app := "test_get_pass_vault"
   136  		pc := NewConfig(app, test.TestData, test.TestData, app, typeVault)
   137  		pass, err := pc.GetPassword("/secret/data/test2", "password")
   138  		expected := "Hashi345"
   139  		assert.NoErrorf(t, err, "Got unexpected error: %s", err)
   140  		assert.Equal(t, expected, pass, "Answer not expected. exp:%s,act:%s", expected, pass)
   141  	})
   142  }