瀏覽代碼

feat: implement GetSecretMap for Bitwarden provider (#3800)

Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
Gergely Brautigam 1 年之前
父節點
當前提交
34a1a50609
共有 2 個文件被更改,包括 119 次插入1 次删除
  1. 24 1
      pkg/provider/bitwarden/client.go
  2. 95 0
      pkg/provider/bitwarden/client_test.go

+ 24 - 1
pkg/provider/bitwarden/client.go

@@ -16,6 +16,7 @@ package bitwarden
 
 import (
 	"context"
+	"encoding/json"
 	"errors"
 	"fmt"
 
@@ -205,7 +206,29 @@ func (p *Provider) SecretExists(ctx context.Context, ref esv1beta1.PushSecretRem
 
 // GetSecretMap returns multiple k/v pairs from the provider.
 func (p *Provider) GetSecretMap(ctx context.Context, ref esv1beta1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
-	return nil, errors.New("GetSecretMap() not implemented")
+	data, err := p.GetSecret(ctx, ref)
+	if err != nil {
+		return nil, err
+	}
+
+	kv := make(map[string]json.RawMessage)
+	err = json.Unmarshal(data, &kv)
+	if err != nil {
+		return nil, fmt.Errorf("error unmarshalling secret: %w", err)
+	}
+
+	secretData := make(map[string][]byte)
+	for k, v := range kv {
+		var strVal string
+		err = json.Unmarshal(v, &strVal)
+		if err == nil {
+			secretData[k] = []byte(strVal)
+		} else {
+			secretData[k] = v
+		}
+	}
+
+	return secretData, nil
 }
 
 // GetAllSecrets gets multiple secrets from the provider and loads into a kubernetes secret.

+ 95 - 0
pkg/provider/bitwarden/client_test.go

@@ -823,3 +823,98 @@ func TestProviderSecretExists(t *testing.T) {
 		})
 	}
 }
+
+func TestProviderGetSecretMap(t *testing.T) {
+	type fields struct {
+		kube      func() client.Client
+		namespace string
+		store     v1beta1.GenericStore
+		mock      func(c *FakeClient)
+	}
+	type args struct {
+		ctx context.Context
+		ref v1beta1.ExternalSecretDataRemoteRef
+		key string
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		want    []byte
+		wantErr bool
+	}{
+		{
+			name: "get secret map",
+			fields: fields{
+				kube: func() client.Client {
+					return fake.NewFakeClient()
+				},
+				namespace: "default",
+				store:     &v1beta1.SecretStore{},
+				mock: func(c *FakeClient) {
+					c.GetSecretReturnsOnCallN(0, &SecretResponse{
+						ID:             "d8f29773-3019-4973-9bbc-66327d077fe2",
+						Key:            "key",
+						Note:           "note",
+						OrganizationID: "org",
+						Value:          `{"key": "value"}`,
+					})
+				},
+			},
+			args: args{
+				ctx: context.Background(),
+				ref: v1beta1.ExternalSecretDataRemoteRef{
+					Key:      "d8f29773-3019-4973-9bbc-66327d077fe2",
+					Property: "key",
+				},
+				key: "key",
+			},
+			want: []byte("value"),
+		},
+		{
+			name: "get secret map - missing key",
+			fields: fields{
+				kube: func() client.Client {
+					return fake.NewFakeClient()
+				},
+				namespace: "default",
+				store:     &v1beta1.SecretStore{},
+				mock: func(c *FakeClient) {
+					c.GetSecretReturnsOnCallN(0, &SecretResponse{
+						ID:             "d8f29773-3019-4973-9bbc-66327d077fe2",
+						Key:            "key",
+						Note:           "note",
+						OrganizationID: "org",
+						Value:          `{"key": "value"}`,
+					})
+				},
+			},
+			args: args{
+				ctx: context.Background(),
+				ref: v1beta1.ExternalSecretDataRemoteRef{
+					Key:      "d8f29773-3019-4973-9bbc-66327d077fe2",
+					Property: "nope",
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			fakeClient := &FakeClient{}
+			tt.fields.mock(fakeClient)
+
+			p := &Provider{
+				kube:               tt.fields.kube(),
+				namespace:          tt.fields.namespace,
+				store:              tt.fields.store,
+				bitwardenSdkClient: fakeClient,
+			}
+			got, err := p.GetSecretMap(tt.args.ctx, tt.args.ref)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("GetSecret() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			assert.Equal(t, tt.want, got[tt.args.key])
+		})
+	}
+}