Browse Source

feat: supporting pushing entire secret for bitwarden provider (#4106)

Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
Gergely Brautigam 1 year ago
parent
commit
7b7dad464d
2 changed files with 85 additions and 7 deletions
  1. 21 7
      pkg/provider/bitwarden/client.go
  2. 64 0
      pkg/provider/bitwarden/client_test.go

+ 21 - 7
pkg/provider/bitwarden/client.go

@@ -47,17 +47,31 @@ func (p *Provider) PushSecret(ctx context.Context, secret *corev1.Secret, data e
 		return errors.New("store does not have a provider")
 		return errors.New("store does not have a provider")
 	}
 	}
 
 
-	if data.GetSecretKey() == "" {
-		return errors.New("pushing the whole secret is not yet implemented")
-	}
-
 	if data.GetRemoteKey() == "" {
 	if data.GetRemoteKey() == "" {
 		return errors.New("remote key must be defined")
 		return errors.New("remote key must be defined")
 	}
 	}
 
 
-	value, ok := secret.Data[data.GetSecretKey()]
-	if !ok {
-		return fmt.Errorf("failed to find secret key in secret with key: %s", data.GetSecretKey())
+	var (
+		value []byte
+		err   error
+		ok    bool
+	)
+	if data.GetSecretKey() == "" {
+		decodedMap := make(map[string]string)
+		for k, v := range secret.Data {
+			decodedMap[k] = string(v)
+		}
+		value, err = utils.JSONMarshal(decodedMap)
+
+		if err != nil {
+			return fmt.Errorf("failed to marshal secret data: %w", err)
+		}
+	} else {
+		value, ok = secret.Data[data.GetSecretKey()]
+
+		if !ok {
+			return fmt.Errorf("failed to find secret key in secret with key: %s", data.GetSecretKey())
+		}
 	}
 	}
 
 
 	note, err := utils.FetchValueFromMetadata(NoteMetadataKey, data.GetMetadata(), "")
 	note, err := utils.FetchValueFromMetadata(NoteMetadataKey, data.GetMetadata(), "")

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

@@ -482,6 +482,70 @@ func TestProviderPushSecret(t *testing.T) {
 			},
 			},
 		},
 		},
 		{
 		{
+			name: "push entire secret succeeds",
+			args: args{
+				ctx: context.Background(),
+				secret: &corev1.Secret{
+					Data: map[string][]byte{
+						"key": []byte("value"),
+					},
+				},
+				data: v1alpha1.PushSecretData{
+					Match: v1alpha1.PushSecretMatch{
+						RemoteRef: v1alpha1.PushSecretRemoteRef{
+							RemoteKey: "this-is-a-name",
+						},
+					},
+				},
+			},
+			fields: fields{
+				kube: func() client.Client {
+					return fake.NewFakeClient()
+				},
+				namespace: "default",
+				store: &v1beta1.SecretStore{
+					Spec: v1beta1.SecretStoreSpec{
+						Provider: &v1beta1.SecretStoreProvider{
+							BitwardenSecretsManager: &v1beta1.BitwardenSecretsManagerProvider{
+								OrganizationID: "orgid",
+								ProjectID:      projectID,
+							},
+						},
+					},
+				},
+				mock: func(c *FakeClient) {
+					c.ListSecretReturnsOnCallN(0, &SecretIdentifiersResponse{
+						Data: []SecretIdentifierResponse{
+							{
+								ID:             "d8f29773-3019-4973-9bbc-66327d077fe2",
+								Key:            "this-is-a-name",
+								OrganizationID: "orgid",
+							},
+						},
+					})
+					c.GetSecretReturnsOnCallN(0, &SecretResponse{
+						ID:             "d8f29773-3019-4973-9bbc-66327d077fe2",
+						Key:            "no-match", // if this is this-is-a-name it would match
+						Note:           "",
+						OrganizationID: "orgid",
+						Value:          "value",
+						ProjectID:      &projectID,
+					})
+					c.CreateSecretReturnsOnCallN(0, &SecretResponse{})
+				},
+				assertMock: func(t *testing.T, c *FakeClient) {
+					cargs := c.createSecretCallArguments[0]
+					assert.Equal(t, SecretCreateRequest{
+						Key:            "this-is-a-name",
+						Note:           "",
+						OrganizationID: "orgid",
+						ProjectIDS:     []string{projectID},
+						Value:          `{"key":"value"}`,
+					}, cargs)
+				},
+			},
+		},
+		{
 			name: "push secret is successful for a existing remote secret but only the value differs will call update",
 			name: "push secret is successful for a existing remote secret but only the value differs will call update",
 			args: args{
 			args: args{
 				ctx: context.Background(),
 				ctx: context.Background(),