Browse Source

Merge pull request #275 from Jabray5/new-azure-getsecretmap

fix azure GetSecretMap
paul-the-alien[bot] 4 years ago
parent
commit
22632116c2

+ 1 - 3
e2e/suite/azure/azure.go

@@ -35,9 +35,7 @@ var _ = Describe("[azure] ", func() {
 	DescribeTable("sync secrets", framework.TableFunc(f, prov),
 		Entry(common.SimpleDataSync(f)),
 		Entry(common.NestedJSONWithGJSON(f)),
-		// TODO: dataFrom is not working as expected RN
-		// see: https://github.com/external-secrets/external-secrets/issues/263
-		// Entry(common.JSONDataFromSync(f)),
+		Entry(common.JSONDataFromSync(f)),
 		Entry(common.JSONDataWithProperty(f)),
 		Entry(common.JSONDataWithTemplate(f)),
 	)

+ 45 - 38
pkg/provider/azure/keyvault/keyvault.go

@@ -18,7 +18,6 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"path"
 	"strings"
 
 	"github.com/Azure/azure-sdk-for-go/profiles/latest/keyvault/keyvault"
@@ -34,6 +33,10 @@ import (
 	"github.com/external-secrets/external-secrets/pkg/provider/schema"
 )
 
+const (
+	defaultObjType = "secret"
+)
+
 // Provider satisfies the provider interface.
 type Provider struct{}
 
@@ -87,24 +90,15 @@ func newClient(ctx context.Context, store esv1alpha1.GenericStore, kube client.C
 // The Object Type is defined as a prefix in the ref.Name , if no prefix is defined , we assume a secret is required.
 func (a *Azure) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
 	version := ""
-	objectType := "secret"
 	basicClient := a.baseClient
+	objectType, secretName := getObjType(ref)
 
 	if ref.Version != "" {
 		version = ref.Version
 	}
 
-	secretName := ref.Key
-	nameSplitted := strings.Split(secretName, "/")
-
-	if len(nameSplitted) > 1 {
-		objectType = nameSplitted[0]
-		secretName = nameSplitted[1]
-		// TODO: later tokens can be used to read the secret tags
-	}
-
 	switch objectType {
-	case "secret":
+	case defaultObjType:
 		// returns a SecretBundle with the secret value
 		// https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/services/keyvault/v7.0/keyvault#SecretBundle
 		secretResp, err := basicClient.GetSecret(context.Background(), a.vaultURL, secretName, version)
@@ -142,37 +136,36 @@ func (a *Azure) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretData
 }
 
 // Implements store.Client.GetSecretMap Interface.
-// retrieve ALL secrets in a specific keyvault.
-// ExternalSecretDataRemoteRef Key is mandatory, but with current model we do not use its content.
-func (a *Azure) GetSecretMap(ctx context.Context, _ esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
-	basicClient := a.baseClient
-	secretsMap := make(map[string][]byte)
+// New version of GetSecretMap.
+func (a *Azure) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
+	objectType, secretName := getObjType(ref)
 
-	secretListIter, err := basicClient.GetSecretsComplete(context.Background(), a.vaultURL, nil)
-	if err != nil {
-		return nil, err
-	}
-	for secretListIter.NotDone() {
-		secretList := secretListIter.Response().Value
-		for _, secret := range *secretList {
-			if !*secret.Attributes.Enabled {
-				continue
-			}
-			secretName := path.Base(*secret.ID)
-			secretResp, err := basicClient.GetSecret(context.Background(), a.vaultURL, secretName, "")
-			secretValue := *secretResp.Value
-
-			if err != nil {
-				return nil, err
-			}
-			secretsMap[secretName] = []byte(secretValue)
-		}
-		err = secretListIter.Next()
+	switch objectType {
+	case defaultObjType:
+		data, err := a.GetSecret(ctx, ref)
 		if err != nil {
 			return nil, err
 		}
+
+		kv := make(map[string]string)
+		err = json.Unmarshal(data, &kv)
+		if err != nil {
+			return nil, fmt.Errorf("error unmarshalling json data: %w", err)
+		}
+
+		secretData := make(map[string][]byte)
+		for k, v := range kv {
+			secretData[k] = []byte(v)
+		}
+
+		return secretData, nil
+	case "cert":
+		return nil, fmt.Errorf("cannot get use dataFrom to get certificate secret")
+	case "key":
+		return nil, fmt.Errorf("cannot get use dataFrom to get key secret")
 	}
-	return secretsMap, nil
+
+	return nil, fmt.Errorf("unknown Azure Keyvault object Type for %s", secretName)
 }
 
 func (a *Azure) newAzureClient(ctx context.Context) (*keyvault.BaseClient, string, error) {
@@ -237,3 +230,17 @@ func (a *Azure) secretKeyRef(ctx context.Context, namespace string, secretRef sm
 func (a *Azure) Close() error {
 	return nil
 }
+
+func getObjType(ref esv1alpha1.ExternalSecretDataRemoteRef) (string, string) {
+	objectType := defaultObjType
+
+	secretName := ref.Key
+	nameSplitted := strings.Split(secretName, "/")
+
+	if len(nameSplitted) > 1 {
+		objectType = nameSplitted[0]
+		secretName = nameSplitted[1]
+		// TODO: later tokens can be used to read the secret tags
+	}
+	return objectType, secretName
+}

+ 5 - 16
pkg/provider/azure/keyvault/keyvault_test.go

@@ -157,26 +157,15 @@ func TestGetSecretWithoutVersion(t *testing.T) {
 func TestGetSecretMap(t *testing.T) {
 	testAzure, azureMock := newAzure()
 	ctx := context.Background()
-	rf := esv1alpha1.ExternalSecretDataRemoteRef{}
-	azureMock.AddSecret(testAzure.vaultURL, "testName", "My Secret", true)
-	azureMock.ExpectsGetSecretsComplete(ctx, testAzure.vaultURL, nil)
+	rf := esv1alpha1.ExternalSecretDataRemoteRef{
+		Key: "testName",
+	}
+	azureMock.AddSecret(testAzure.vaultURL, "testName", "{\"username\": \"user1\", \"pass\": \"123\"}", true)
 	azureMock.ExpectsGetSecret(ctx, testAzure.vaultURL, "testName", "")
 	secretMap, err := testAzure.GetSecretMap(ctx, rf)
 	azureMock.AssertExpectations(t)
 	tassert.Nil(t, err, "the return err should be nil")
-	tassert.Equal(t, secretMap, map[string][]byte{"testName": []byte("My Secret")})
-}
-
-func TestGetSecretMapNotEnabled(t *testing.T) {
-	testAzure, azureMock := newAzure()
-	ctx := context.Background()
-	rf := esv1alpha1.ExternalSecretDataRemoteRef{}
-	azureMock.AddSecret(testAzure.vaultURL, "testName", "My Secret", false)
-	azureMock.ExpectsGetSecretsComplete(ctx, testAzure.vaultURL, nil)
-	secretMap, err := testAzure.GetSecretMap(ctx, rf)
-	azureMock.AssertExpectations(t)
-	tassert.Nil(t, err, "the return err should be nil")
-	tassert.Empty(t, secretMap)
+	tassert.Equal(t, secretMap, map[string][]byte{"username": []byte("user1"), "pass": []byte("123")})
 }
 
 func newKVJWK(b []byte) *keyvault.JSONWebKey {