Browse Source

feat: add property feature to gcp

Lucas Severo Alves 4 years ago
parent
commit
3c26b806bc

+ 1 - 1
docs/provider-google-secrets-manager.md

@@ -31,5 +31,5 @@ To create a kubernetes secret from the GCP Secret Manager secret a `Kind=Externa
 
 The operator will fetch the GCP Secret Manager secret and inject it as a `Kind=Secret`
 ```
-kubectl get secret secret-to-be-created -n <namespace> | -o jsonpath='{.data.example-externalsecret-key}' | base64 -d
+kubectl get secret secret-to-be-created -n <namespace> | -o jsonpath='{.data.dev-secret-test}' | base64 -d
 ```

+ 2 - 2
e2e/suite/aws/secretsmanager.go

@@ -134,7 +134,7 @@ var _ = Describe("[aws] ", func() {
 	})
 
 	It("should sync secrets with dataFrom", func() {
-		By("creating a GCP SM Secret")
+		By("creating a AWS SM Secret")
 		secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one")
 		targetSecretKey1 := "name"
 		targetSecretValue1 := "great-name"
@@ -174,7 +174,7 @@ var _ = Describe("[aws] ", func() {
 	})
 
 	It("should sync secrets and get inner keys", func() {
-		By("creating a GCP SM Secret")
+		By("creating a AWS SM Secret")
 		secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one")
 		targetSecretKey1 := "firstname"
 		targetSecretValue1 := "Tom"

+ 67 - 2
e2e/suite/gcp/gcp.go

@@ -29,6 +29,10 @@ import (
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
 
+const (
+	targetSecret = "target-secret"
+)
+
 var _ = Describe("[gcp] ", func() {
 	f := framework.New("eso-gcp")
 	var secretStore *esv1alpha1.SecretStore
@@ -77,7 +81,6 @@ var _ = Describe("[gcp] ", func() {
 		By("creating a GCP SM Secret")
 		secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one")
 		secretValue := "great-value-test"
-		targetSecret := "target-secret"
 		secret, err := createGCPSecretsManagerSecret(
 			projectID,
 			secretKey1, secretValue, []byte(credentials))
@@ -123,7 +126,6 @@ var _ = Describe("[gcp] ", func() {
 		targetSecretKey2 := "surname"
 		targetSecretValue2 := "great-surname"
 		secretValue := fmt.Sprintf("{ \"%s\": \"%s\", \"%s\": \"%s\" }", targetSecretKey1, targetSecretValue1, targetSecretKey2, targetSecretValue2)
-		targetSecret := "target-secret"
 		secret, err := createGCPSecretsManagerSecret(
 			projectID,
 			secretKey1, secretValue, []byte(credentials))
@@ -159,4 +161,67 @@ var _ = Describe("[gcp] ", func() {
 		Expect(err).ToNot(HaveOccurred())
 	})
 
+	It("should sync secrets and get inner keys", func() {
+		By("creating a GCP SM Secret")
+		secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one")
+		targetSecretKey1 := "firstname"
+		targetSecretValue1 := "Tom"
+		targetSecretKey2 := "first_friend"
+		targetSecretValue2 := "Roger"
+		secretValue := fmt.Sprintf(
+			`{
+				"name": {"first": "%s", "last": "Anderson"},
+				"friends": 
+				[ 
+					{"first": "Dale", "last": "Murphy"}, 
+					{"first": "%s", "last": "Craig"}, 
+					{"first": "Jane", "last": "Murphy"} 
+				]
+			}`, targetSecretValue1, targetSecretValue2)
+		secret, err := createGCPSecretsManagerSecret(
+			projectID,
+			secretKey1, secretValue, []byte(credentials))
+		Expect(err).ToNot(HaveOccurred())
+		err = f.CRClient.Create(context.Background(), &esv1alpha1.ExternalSecret{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "datafrom-sync",
+				Namespace: f.Namespace.Name,
+			},
+			Spec: esv1alpha1.ExternalSecretSpec{
+				SecretStoreRef: esv1alpha1.SecretStoreRef{
+					Name: f.Namespace.Name,
+				},
+				Target: esv1alpha1.ExternalSecretTarget{
+					Name: targetSecret,
+				},
+				Data: []esv1alpha1.ExternalSecretData{
+					{
+						SecretKey: targetSecretKey1,
+						RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+							Key:      secretKey1,
+							Property: "name.first",
+						},
+					},
+					{
+						SecretKey: targetSecretKey2,
+						RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+							Key:      secretKey1,
+							Property: "friends.1.first",
+						},
+					},
+				},
+			},
+		})
+		Expect(err).ToNot(HaveOccurred())
+
+		_, err = f.WaitForSecretValue(f.Namespace.Name, targetSecret, map[string][]byte{
+			targetSecretKey1: []byte(targetSecretValue1),
+			targetSecretKey2: []byte(targetSecretValue2),
+		})
+		Expect(err).ToNot(HaveOccurred())
+
+		err = deleteGCPSecretsManagerSecret(secret.Name, []byte(credentials))
+		Expect(err).ToNot(HaveOccurred())
+	})
+
 })

+ 14 - 5
pkg/provider/gcp/secretmanager/secretsmanager.go

@@ -20,6 +20,7 @@ import (
 
 	secretmanager "cloud.google.com/go/secretmanager/apiv1"
 	"github.com/googleapis/gax-go"
+	"github.com/tidwall/gjson"
 	"golang.org/x/oauth2/google"
 	"google.golang.org/api/option"
 	secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1"
@@ -45,7 +46,6 @@ const (
 	errUnableCreateGCPSMClient                = "failed to create GCP secretmanager client: %w"
 	errUninitalizedGCPProvider                = "provider GCP is not initialized"
 	errClientGetSecretAccess                  = "unable to access Secret from SecretManager Client: %w"
-	errClientClose                            = "unable to close SecretManager client: %w"
 	errJSONSecretUnmarshal                    = "unable to unmarshal secret: %w"
 )
 
@@ -153,12 +153,21 @@ func (sm *ProviderGCP) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSec
 		return nil, fmt.Errorf(errClientGetSecretAccess, err)
 	}
 
-	err = sm.SecretManagerClient.Close()
-	if err != nil {
-		return nil, fmt.Errorf(errClientClose, err)
+	if ref.Property == "" {
+		if result.Payload.Data != nil {
+			return result.Payload.Data, nil
+		}
+		return nil, fmt.Errorf("invalid secret received. no secret string for key: %s", ref.Key)
 	}
 
-	return result.Payload.Data, nil
+	var payload string
+	if result.Payload.Data != nil {
+		payload = string(result.Payload.Data)
+	}
+
+	val := gjson.Get(payload, ref.Property)
+
+	return []byte(val.String()), nil
 }
 
 // GetSecretMap returns multiple k/v pairs from the provider.