Skip to content

Commit

Permalink
Merge pull request #2 from kir4h/dont_mock_vault_for_testing
Browse files Browse the repository at this point in the history
Use vault testing utilities instead of mocking
  • Loading branch information
kir4h committed Jul 28, 2020
2 parents 200ad47 + d7a01bd commit 0c74d82
Show file tree
Hide file tree
Showing 14 changed files with 1,001 additions and 348 deletions.
15 changes: 3 additions & 12 deletions go.mod
Expand Up @@ -3,29 +3,20 @@ module rvault
go 1.14

require (
github.com/fatih/color v1.9.0 // indirect
github.com/frankban/quicktest v1.4.1 // indirect
github.com/go-test/deep v1.0.2 // indirect
github.com/gobwas/glob v0.2.3
github.com/google/go-cmp v0.4.1 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/vault v1.4.3
github.com/hashicorp/vault-plugin-secrets-kv v0.5.5
github.com/hashicorp/vault/api v1.0.5-0.20200317185738-82f498082f02
github.com/hashicorp/vault/sdk v0.1.14-0.20200429182704-29fce8f27ce4 // indirect
github.com/kr/pretty v0.2.0 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/hashicorp/vault/sdk v0.1.14-0.20200702114606-96dd7d6e10db
github.com/mitchellh/go-homedir v1.1.0
github.com/pierrec/lz4 v2.2.6+incompatible // indirect
github.com/spf13/afero v1.1.2
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.3
github.com/spf13/viper v1.7.0
github.com/stretchr/testify v1.4.0 // indirect
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad // indirect
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 // indirect
golang.org/x/sys v0.0.0-20200523222454-059865788121 // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/square/go-jose.v2 v2.4.1 // indirect
gopkg.in/yaml.v2 v2.2.8
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.3.0
Expand Down
544 changes: 542 additions & 2 deletions go.sum

Large diffs are not rendered by default.

35 changes: 4 additions & 31 deletions internal/pkg/api/client.go
Expand Up @@ -9,18 +9,6 @@ import (
"k8s.io/klog"
)

// VaultClient is an interface that describes a vault Client.
type VaultClient interface {
List(path string) (*vapi.Secret, error)
Read(path string) (*vapi.Secret, error)
ListMounts() (map[string]*vapi.MountOutput, error)
}

// Client is an implementation of a vault Client interface.
type Client struct {
VC *vapi.Client
}

func getVaultConfig() (*vapi.Config, error) {
vaultAddress := viper.GetString("global.address")
if vaultAddress == "" {
Expand All @@ -45,23 +33,8 @@ func getVaultToken() (string, error) {
return vaultToken, nil
}

// List lists Vault secrets
func (c *Client) List(path string) (*vapi.Secret, error) {
return c.VC.Logical().List(path)
}

// Read reads Vault secrets
func (c *Client) Read(path string) (*vapi.Secret, error) {
return c.VC.Logical().Read(path)
}

// ListMounts list Vault Mounts
func (c *Client) ListMounts() (map[string]*vapi.MountOutput, error) {
return c.VC.Sys().ListMounts()
}

// NewClient returns a new Client
func NewClient() (*Client, error) {
func NewClient() (*vapi.Client, error) {
config, err := getVaultConfig()
if err != nil {
return nil, err
Expand All @@ -71,12 +44,12 @@ func NewClient() (*Client, error) {
return nil, err
}

vc, err := vapi.NewClient(config)
c, err := vapi.NewClient(config)
if err != nil {
return nil, err
}
fmt.Printf("ADDRESS IS %s\n", c.Address())

c := &Client{vc}
c.VC.SetToken(vaultToken)
c.SetToken(vaultToken)
return c, nil
}
18 changes: 13 additions & 5 deletions internal/pkg/api/client_test.go
Expand Up @@ -21,29 +21,37 @@ func TestNewClient(t *testing.T) {
wantErr bool
}{
{
name: "Smoke_Test",
name: "Smoke Test",
token: smokeTestToken,
address: smokeTestAddress,
wantToken: smokeTestToken,
wantAddress: "http://" + smokeTestAddress,
wantErr: false,
},
{
name: "Fail_Missing_Address",
name: "Fail on Missing Address",
token: smokeTestToken,
address: "",
wantToken: "",
wantAddress: "",
wantErr: true,
},
{
name: "Fail_Missing_Token",
name: "Fail on Missing Token",
token: "",
address: smokeTestAddress,
wantToken: "",
wantAddress: "",
wantErr: true,
},
{
name: "Fail on invalid URL",
token: smokeTestToken,
address: ":invalid/",
wantToken: "",
wantAddress: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -56,8 +64,8 @@ func TestNewClient(t *testing.T) {
}

if got != nil {
gotToken := got.VC.Token()
gotAddress := got.VC.Address()
gotToken := got.Token()
gotAddress := got.Address()
if tt.wantToken != gotToken {
t.Errorf("got = %s, want %s", gotToken, tt.wantToken)
}
Expand Down
12 changes: 6 additions & 6 deletions internal/pkg/api/path_test.go
Expand Up @@ -18,7 +18,7 @@ func TestGetBasePath(t *testing.T) {
wantErr bool
}{
{
name: "V1",
name: "Smoke V1",
args: args{
engine: "secret",
kvVersion: "1",
Expand All @@ -27,7 +27,7 @@ func TestGetBasePath(t *testing.T) {
wantErr: false,
},
{
name: "V2",
name: "Smoke V2",
args: args{
engine: "secret",
kvVersion: "2",
Expand All @@ -36,7 +36,7 @@ func TestGetBasePath(t *testing.T) {
wantErr: false,
},
{
name: "Unsupported Version",
name: "Fail on Unsupported Version",
args: args{
engine: "secret",
kvVersion: "99",
Expand Down Expand Up @@ -72,7 +72,7 @@ func TestGetReadBasePath(t *testing.T) {
wantErr bool
}{
{
name: "V1",
name: "Smoke Test V1",
args: args{
engine: "secret",
kvVersion: "1",
Expand All @@ -81,7 +81,7 @@ func TestGetReadBasePath(t *testing.T) {
wantErr: false,
},
{
name: "V2",
name: "Smoke Test V2",
args: args{
engine: "secret",
kvVersion: "2",
Expand All @@ -90,7 +90,7 @@ func TestGetReadBasePath(t *testing.T) {
wantErr: false,
},
{
name: "Unsupported Version",
name: "Fail on Unsupported Version",
args: args{
engine: "secret",
kvVersion: "99",
Expand Down
8 changes: 3 additions & 5 deletions internal/pkg/kv/kv.go
Expand Up @@ -4,8 +4,6 @@ import (
"fmt"
"strings"

"rvault/internal/pkg/api"

vapi "github.com/hashicorp/vault/api"
"github.com/spf13/viper"
"k8s.io/klog/v2"
Expand Down Expand Up @@ -52,8 +50,8 @@ func getDataValueFromResult(result readResult, kvVersion string) (interface{}, e
}
}

func getMountOutput(c api.VaultClient, engine string) (*vapi.MountOutput, error) {
mounts, err := c.ListMounts()
func getMountOutput(c *vapi.Client, engine string) (*vapi.MountOutput, error) {
mounts, err := c.Sys().ListMounts()
if err != nil {
return nil, err
}
Expand All @@ -67,7 +65,7 @@ func getMountOutput(c api.VaultClient, engine string) (*vapi.MountOutput, error)
}
}

func getKVVersion(c api.VaultClient, engine string) (string, error) {
func getKVVersion(c *vapi.Client, engine string) (string, error) {
// look for engine specific setting
version := viper.GetString(fmt.Sprintf("engines.%s.kv_version", engine))
if version == "" {
Expand Down
96 changes: 66 additions & 30 deletions internal/pkg/kv/kv_test.go
@@ -1,35 +1,20 @@
package kv_test

import (
"testing"

kv "github.com/hashicorp/vault-plugin-secrets-kv"
vapi "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/sdk/logical"
"github.com/hashicorp/vault/vault"
)

type testClient struct {
engine string
kvVersion string
engineType string
secretPaths map[string][]interface{}
secrets map[string]map[string]interface{}
listErr error
readErr error
}

var secretPaths map[string][]interface{}
var secrets map[string]map[string]interface{}
var engine = "secret"
var engineV2 = "secretv2"

func init() {
secretPaths = map[string][]interface{}{
"/": {"spain/", "france/", "uk/"},
"/spain/": {"malaga/", "admin"},
"/spain/malaga/": {"random"},
"/france/": {"paris/", "nantes/"},
"/france/paris/": {"key"},
"/france/nantes/": {""},
"/uk/": {"london/"},
"/uk/london/": {"mi5"},
}

secrets = map[string]map[string]interface{}{
"/spain/admin": {
"admin.conf": "dsfdsflfrf43l4tlp",
Expand All @@ -41,19 +26,70 @@ func init() {
"id_rsa": "ewdfpelfr23pwlrp32l4[p23lp2k",
"id_dsa": "fewfowefkfkwepfkewkfpweokfeowkfpk",
},
"/france/nantes/dummy": {
"": "",
},
"/uk/london/mi5": {
"mi5.conf": "salt, 324r23432, false",
},
}
}

func (tc *testClient) ListMounts() (map[string]*vapi.MountOutput, error) {
return map[string]*vapi.MountOutput{
tc.engine + "/": {
Type: tc.engineType,
Options: map[string]string{
"version": tc.kvVersion,
},
func writeSecret(t *testing.T, c *vapi.Client, path string, content map[string]interface{}) {
t.Helper()
_, err := c.Logical().Write(path, content)
if err != nil {
t.Fatal(err)
}
}

func deleteSecret(t *testing.T, c *vapi.Client, path string) {
t.Helper()
_, err := c.Logical().Delete(path)
if err != nil {
t.Fatal(err)
}
}

func createSecretsV1(t *testing.T, c *vapi.Client, engine string, secrets map[string]map[string]interface{}) {
t.Helper()
for path, content := range secrets {
writeSecret(t, c, engine+path, content)
}
}

func createSecretsV2(t *testing.T, c *vapi.Client, engine string, secrets map[string]map[string]interface{}) {
t.Helper()
for path, content := range secrets {
writeSecret(t, c, engine+"/data"+path, map[string]interface{}{"data": content})
}
}

func createTestVault(t *testing.T) *vault.TestCluster {
t.Helper()

coreConfig := &vault.CoreConfig{
LogicalBackends: map[string]logical.Factory{
"kv": kv.Factory,
},
}, nil
}
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
HandlerFunc: http.Handler,
})
cluster.Start()
client := cluster.Cores[0].Client
err := cluster.Cores[0].Client.Sys().Mount("secretv2", &vapi.MountInput{
Type: "kv",
Options: map[string]string{"version": "2"},
})
if err != nil {
t.Fatal(err)
}

createSecretsV1(t, client, "secret", secrets)
deleteSecret(t, client, "secret/france/nantes/dummy")
createSecretsV2(t, client, "secretv2", secrets)
deleteSecret(t, client, "secretv2/metadata/france/nantes/dummy")

return cluster
}

0 comments on commit 0c74d82

Please sign in to comment.