From 68556081934f8a9ed070498af648e9768f99cf1c Mon Sep 17 00:00:00 2001 From: Felix Fritzsche Date: Tue, 28 May 2024 14:37:41 +0200 Subject: [PATCH] Adding first simple key value implementation --- client.go | 10 +++- kv_v1.go | 77 ++++++++++++++++++++++++++++++ kv_v1_test.go | 81 ++++++++++++++++++++++++++++++++ test/testdata/container_vault.go | 47 +++++++++++++----- 4 files changed, 203 insertions(+), 12 deletions(-) create mode 100644 kv_v1.go create mode 100644 kv_v1_test.go diff --git a/client.go b/client.go index c464156..3f02cd2 100644 --- a/client.go +++ b/client.go @@ -70,7 +70,11 @@ func NewClient(addr string, tlsConf *TLSConfig, opts ...ClientOpts) (*Client, er return nil, err } - client := &Client{Client: vaultClient, conf: conf, tlsConf: tlsConf} + client := &Client{ + Client: vaultClient, + conf: conf, + tlsConf: tlsConf, + } for _, opt := range opts { err := opt(client) @@ -184,3 +188,7 @@ func (c *Client) Delete(path []string, body, response interface{}, opts *Request func (c *Client) List(path []string, body, response interface{}, opts *RequestOptions) error { return c.Request("LIST", path, body, response, opts) } + +func (c *Client) Put(path []string, body, response interface{}, opts *RequestOptions) error { + return c.Request("PUT", path, body, response, opts) +} diff --git a/kv_v1.go b/kv_v1.go new file mode 100644 index 0000000..a68568d --- /dev/null +++ b/kv_v1.go @@ -0,0 +1,77 @@ +package vault + +import ( + "net/url" +) + +const ( + pathPrefix string = "v1" +) + +type KVv1 struct { + Service +} + +func (c *Client) KVv1() *KVv1 { + return c.KVv1WithMountPoint("kv") +} + +func (c *Client) KVv1WithMountPoint(mountPoint string) *KVv1 { + return &KVv1{ + Service: Service{ + client: c, + MountPoint: mountPoint, + }, + } +} + +func (k *KVv1) Create(id string, data map[string]string) error { + err := k.client.Write( + []string{ + pathPrefix, + k.MountPoint, + url.PathEscape(id), + }, data, nil, nil, + ) + if err != nil { + return err + } + + return nil +} + +type KVv1ReadResponse struct { + Data map[string]string `json:"data"` +} + +func (k *KVv1) Read(key string) (*KVv1ReadResponse, error) { + readRes := &KVv1ReadResponse{} + + err := k.client.Read( + []string{ + pathPrefix, + k.MountPoint, + url.PathEscape(key), + }, readRes, nil, + ) + if err != nil { + return nil, err + } + + return readRes, nil +} + +func (k *KVv1) Delete(key string) error { + err := k.client.Delete( + []string{ + pathPrefix, + k.MountPoint, + url.PathEscape(key), + }, nil, nil, nil, + ) + if err != nil { + return err + } + + return nil +} diff --git a/kv_v1_test.go b/kv_v1_test.go new file mode 100644 index 0000000..d64512a --- /dev/null +++ b/kv_v1_test.go @@ -0,0 +1,81 @@ +package vault_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + vault "github.com/mittwald/vaultgo" + "github.com/mittwald/vaultgo/test/testdata" + + "github.com/stretchr/testify/suite" +) + +type KVv1TestSuite struct { + suite.Suite + client *vault.KVv1 +} + +func TestKVv1TestSuite(t *testing.T) { + for _, v := range testdata.VaultVersions { + require.NoError(t, testdata.Init(context.Background(), v)) + + t.Logf("using vault uri %v", testdata.Vault.URI()) + client, _ := vault.NewClient(testdata.Vault.URI(), vault.WithCaPath("")) + client.SetToken(testdata.Vault.Token()) + keyValue := client.KVv1() + + keyValueTestSuite := new(KVv1TestSuite) + keyValueTestSuite.client = keyValue + + suite.Run(t, keyValueTestSuite) + } +} + +func (s *KVv1TestSuite) TestCreateAndRead() { + testKeyValues := make(map[string]string) + testKeyValues["PrivateKey"] = "abcde" + + err := s.client.Create("9697fdce-39df-45ac-9115-5e3913c34613", testKeyValues) + require.NoError(s.T(), err) + + readResponse, readErr := s.client.Read("9697fdce-39df-45ac-9115-5e3913c34613") + require.NoError(s.T(), readErr) + + require.Equal(s.T(), readResponse.Data, testKeyValues) +} + +func (s *KVv1TestSuite) TestOverwriteAndRead() { + testKeyValues := make(map[string]string) + testKeyValues["PrivateKey"] = "abcde" + testKeyValues["PrivateKey2"] = "fghji" + + err := s.client.Create("9697fdce-39df-45ac-9115-5e3913c34613", testKeyValues) + require.NoError(s.T(), err) + + testKeyValuesNew := make(map[string]string) + testKeyValuesNew["PrivateKey"] = "klmnop" + + err = s.client.Create("9697fdce-39df-45ac-9115-5e3913c34613", testKeyValuesNew) + require.NoError(s.T(), err) + + readResponse, readErr := s.client.Read("9697fdce-39df-45ac-9115-5e3913c34613") + require.NoError(s.T(), readErr) + + require.Equal(s.T(), readResponse.Data, testKeyValuesNew) +} + +func (s *KVv1TestSuite) TestCreateAndDelete() { + testKeyValues := make(map[string]string) + testKeyValues["PrivateKey"] = "abcde" + + err := s.client.Create("2b7ff26d-30b7-43ba-96d5-79b4baba9b39", testKeyValues) + require.NoError(s.T(), err) + + deleteErr := s.client.Delete("2b7ff26d-30b7-43ba-96d5-79b4baba9b39") + require.NoError(s.T(), deleteErr) + + _, readErr := s.client.Read("2b7ff26d-30b7-43ba-96d5-79b4baba9b39") + require.Error(s.T(), readErr) +} diff --git a/test/testdata/container_vault.go b/test/testdata/container_vault.go index 1141d8e..f50bf98 100644 --- a/test/testdata/container_vault.go +++ b/test/testdata/container_vault.go @@ -9,7 +9,13 @@ import ( "github.com/testcontainers/testcontainers-go/wait" ) -var VaultVersions = []string{"1.6.7", "1.7.5", "1.8.4", "1.9.3", "1.12.2"} +var VaultVersions = []string{ + "1.6.7", + "1.7.5", + "1.8.4", + "1.9.3", + "1.12.2", +} type VaultContainer struct { container testcontainers.Container @@ -59,10 +65,12 @@ func InitVaultContainer(ctx context.Context, version string) (*VaultContainer, e Privileged: true, } - v, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ContainerRequest: req, - Started: true, - }) + v, err := testcontainers.GenericContainer( + ctx, testcontainers.GenericContainerRequest{ + ContainerRequest: req, + Started: true, + }, + ) if err != nil { return nil, err } @@ -84,12 +92,29 @@ func InitVaultContainer(ctx context.Context, version string) (*VaultContainer, e return nil, err } - _, _, err = vc.container.Exec(ctx, []string{ - "vault", - "secrets", - "enable", - "transit", - }) + // transit mount + _, _, err = vc.container.Exec( + ctx, []string{ + "vault", + "secrets", + "enable", + "transit", + }, + ) + if err != nil { + return nil, err + } + + // KVv1 mount + _, _, err = vc.container.Exec( + ctx, []string{ + "vault", + "secrets", + "enable", + "-version=1", + "kv", + }, + ) if err != nil { return nil, err }