Browse Source

Modified CRD according to the discussion

Sebastian Gomez 4 years ago
parent
commit
f4d1b8dd22

+ 21 - 21
apis/externalsecrets/v1alpha1/externalsecret_types.go

@@ -118,24 +118,17 @@ type ExternalSecretData struct {
 
 // ExternalSecretDataRemoteRef defines Provider data location.
 type ExternalSecretDataRemoteRef struct {
-	// Key is the key used in the Provider
-	// +optional
-	Key string `json:"key,omitempty"`
-
-	// Used to select multiple secrets based on a pattern
-	// +optional
-	MatchKey string `json:"matchKey,omitempty"`
-
-	// List of tags used to filter the secrets
-	Tags map[string]string `json:"tags,omitempty"`
-
-	// Used to select multiple secrets based on the name
+	// Used to select a specific version and property from the secret
 	// +optional
-	Name string `json:"name,omitempty"`
+	Extract ExternalSecretExtract `json:"extract,omitempty"`
+	// Used to find secrets based on tags or regular expressions
+	Find ExternalSecretFind `json:"find,omitempty"`
+}
 
-	// Used to select multiple secrets based on a regular expression of the name
+type ExternalSecretExtract struct {
+	// Key is the key used in the Provider
 	// +optional
-	RegExp string `json:"regexp,omitempty"`
+	Key string `json:"key,omitempty"`
 
 	// Used to select a specific version of the Provider value, if supported
 	// +optional
@@ -146,14 +139,21 @@ type ExternalSecretDataRemoteRef struct {
 	Property string `json:"property,omitempty"`
 }
 
-// type ExternalSecretDataRemoteMatchKey struct {
+type ExternalSecretFind struct {
+	// Key is the key used in the Provider
+	// +optional
+	Name FindName `json:"name,omitempty"`
 
-// 	//A regular expression used to get the secrets
-// 	//Name string `json:"name,omitempty"`
+	// Used to select a specific version of the Provider value, if supported
+	// +optional
+	Tags map[string]string `json:"tags,omitempty"`
+}
 
-// 	// List of tags used to filter the secrets
-// 	Tags map[string]string `json:"tags,omitempty"`
-// }
+type FindName struct {
+	// Used to select multiple secrets based on a regular expression of the name
+	// +optional
+	RegExp string `json:"regexp,omitempty"`
+}
 
 // ExternalSecretSpec defines the desired state of ExternalSecret.
 type ExternalSecretSpec struct {

+ 51 - 3
apis/externalsecrets/v1alpha1/zz_generated.deepcopy.go

@@ -405,6 +405,39 @@ func (in *ExternalSecretData) DeepCopy() *ExternalSecretData {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *ExternalSecretDataRemoteRef) DeepCopyInto(out *ExternalSecretDataRemoteRef) {
 	*out = *in
+	out.Extract = in.Extract
+	in.Find.DeepCopyInto(&out.Find)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretDataRemoteRef.
+func (in *ExternalSecretDataRemoteRef) DeepCopy() *ExternalSecretDataRemoteRef {
+	if in == nil {
+		return nil
+	}
+	out := new(ExternalSecretDataRemoteRef)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ExternalSecretExtract) DeepCopyInto(out *ExternalSecretExtract) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretExtract.
+func (in *ExternalSecretExtract) DeepCopy() *ExternalSecretExtract {
+	if in == nil {
+		return nil
+	}
+	out := new(ExternalSecretExtract)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ExternalSecretFind) DeepCopyInto(out *ExternalSecretFind) {
+	*out = *in
+	out.Name = in.Name
 	if in.Tags != nil {
 		in, out := &in.Tags, &out.Tags
 		*out = make(map[string]string, len(*in))
@@ -414,12 +447,12 @@ func (in *ExternalSecretDataRemoteRef) DeepCopyInto(out *ExternalSecretDataRemot
 	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretDataRemoteRef.
-func (in *ExternalSecretDataRemoteRef) DeepCopy() *ExternalSecretDataRemoteRef {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretFind.
+func (in *ExternalSecretFind) DeepCopy() *ExternalSecretFind {
 	if in == nil {
 		return nil
 	}
-	out := new(ExternalSecretDataRemoteRef)
+	out := new(ExternalSecretFind)
 	in.DeepCopyInto(out)
 	return out
 }
@@ -610,6 +643,21 @@ func (in *ExternalSecretTemplateMetadata) DeepCopy() *ExternalSecretTemplateMeta
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FindName) DeepCopyInto(out *FindName) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FindName.
+func (in *FindName) DeepCopy() *FindName {
+	if in == nil {
+		return nil
+	}
+	out := new(FindName)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *GCPSMAuth) DeepCopyInto(out *GCPSMAuth) {
 	*out = *in

+ 67 - 52
deploy/crds/external-secrets.io_externalsecrets.yaml

@@ -59,34 +59,41 @@ spec:
                       description: ExternalSecretDataRemoteRef defines Provider data
                         location.
                       properties:
-                        key:
-                          description: Key is the key used in the Provider
-                          type: string
-                        matchKey:
-                          description: Used to select multiple secrets based on a
-                            pattern
-                          type: string
-                        name:
-                          description: Used to select multiple secrets based on the
-                            name
-                          type: string
-                        property:
-                          description: Used to select a specific property of the Provider
-                            value (if a map), if supported
-                          type: string
-                        regexp:
-                          description: Used to select multiple secrets based on a
-                            regular expression of the name
-                          type: string
-                        tags:
-                          additionalProperties:
-                            type: string
-                          description: List of tags used to filter the secrets
+                        extract:
+                          description: Used to select a specific version and property
+                            from the secret
+                          properties:
+                            key:
+                              description: Key is the key used in the Provider
+                              type: string
+                            property:
+                              description: Used to select a specific property of the
+                                Provider value (if a map), if supported
+                              type: string
+                            version:
+                              description: Used to select a specific version of the
+                                Provider value, if supported
+                              type: string
+                          type: object
+                        find:
+                          description: Used to find secrets based on tags or regular
+                            expressions
+                          properties:
+                            name:
+                              description: Key is the key used in the Provider
+                              properties:
+                                regexp:
+                                  description: Used to select multiple secrets based
+                                    on a regular expression of the name
+                                  type: string
+                              type: object
+                            tags:
+                              additionalProperties:
+                                type: string
+                              description: Used to select a specific version of the
+                                Provider value, if supported
+                              type: object
                           type: object
-                        version:
-                          description: Used to select a specific version of the Provider
-                            value, if supported
-                          type: string
                       type: object
                     secretKey:
                       type: string
@@ -102,32 +109,40 @@ spec:
                 items:
                   description: ExternalSecretDataRemoteRef defines Provider data location.
                   properties:
-                    key:
-                      description: Key is the key used in the Provider
-                      type: string
-                    matchKey:
-                      description: Used to select multiple secrets based on a pattern
-                      type: string
-                    name:
-                      description: Used to select multiple secrets based on the name
-                      type: string
-                    property:
-                      description: Used to select a specific property of the Provider
-                        value (if a map), if supported
-                      type: string
-                    regexp:
-                      description: Used to select multiple secrets based on a regular
-                        expression of the name
-                      type: string
-                    tags:
-                      additionalProperties:
-                        type: string
-                      description: List of tags used to filter the secrets
+                    extract:
+                      description: Used to select a specific version and property
+                        from the secret
+                      properties:
+                        key:
+                          description: Key is the key used in the Provider
+                          type: string
+                        property:
+                          description: Used to select a specific property of the Provider
+                            value (if a map), if supported
+                          type: string
+                        version:
+                          description: Used to select a specific version of the Provider
+                            value, if supported
+                          type: string
+                      type: object
+                    find:
+                      description: Used to find secrets based on tags or regular expressions
+                      properties:
+                        name:
+                          description: Key is the key used in the Provider
+                          properties:
+                            regexp:
+                              description: Used to select multiple secrets based on
+                                a regular expression of the name
+                              type: string
+                          type: object
+                        tags:
+                          additionalProperties:
+                            type: string
+                          description: Used to select a specific version of the Provider
+                            value, if supported
+                          type: object
                       type: object
-                    version:
-                      description: Used to select a specific version of the Provider
-                        value, if supported
-                      type: string
                   type: object
                 type: array
               refreshInterval:

+ 4 - 4
pkg/controllers/externalsecret/externalsecret_controller.go

@@ -393,15 +393,15 @@ func (r *Reconciler) getProviderSecretData(ctx context.Context, providerClient p
 
 		// If tags were added get all secret by tags
 		// Also if a regular expression was entered
-		if len(remoteRef.Tags) > 0 || len(remoteRef.RegExp) > 0 {
+		if len(remoteRef.Find.Tags) > 0 || len(remoteRef.Find.Name.RegExp) > 0 {
 			secretMap, err = providerClient.GetAllSecrets(ctx, remoteRef)
 			if err != nil {
-				return nil, fmt.Errorf(errGetSecretKey, remoteRef.Key, externalSecret.Name, err)
+				return nil, fmt.Errorf(errGetSecretKey, remoteRef.Extract.Key, externalSecret.Name, err)
 			}
 		} else {
 			secretMap, err = providerClient.GetSecretMap(ctx, remoteRef)
 			if err != nil {
-				return nil, fmt.Errorf(errGetSecretKey, remoteRef.Key, externalSecret.Name, err)
+				return nil, fmt.Errorf(errGetSecretKey, remoteRef.Extract.Key, externalSecret.Name, err)
 			}
 		}
 		providerData = utils.MergeByteMap(providerData, secretMap)
@@ -410,7 +410,7 @@ func (r *Reconciler) getProviderSecretData(ctx context.Context, providerClient p
 	for _, secretRef := range externalSecret.Spec.Data {
 		secretData, err := providerClient.GetSecret(ctx, secretRef.RemoteRef)
 		if err != nil {
-			return nil, fmt.Errorf(errGetSecretKey, secretRef.RemoteRef.Key, externalSecret.Name, err)
+			return nil, fmt.Errorf(errGetSecretKey, secretRef.RemoteRef.Extract.Key, externalSecret.Name, err)
 		}
 
 		providerData[secretRef.SecretKey] = secretData

+ 13 - 5
pkg/controllers/externalsecret/externalsecret_controller_test.go

@@ -218,8 +218,10 @@ var _ = Describe("ExternalSecret controller", func() {
 						{
 							SecretKey: targetProp,
 							RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
-								Key:      remoteKey,
-								Property: remoteProperty,
+								Extract: esv1alpha1.ExternalSecretExtract{
+									Key:      remoteKey,
+									Property: remoteProperty,
+								},
 							},
 						},
 					},
@@ -482,7 +484,9 @@ var _ = Describe("ExternalSecret controller", func() {
 		}
 		tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
 			{
-				Key: "datamap",
+				Extract: esv1alpha1.ExternalSecretExtract{
+					Key: "datamap",
+				},
 			},
 		}
 		fakeProvider.WithGetSecret([]byte(secretVal), nil)
@@ -648,7 +652,9 @@ var _ = Describe("ExternalSecret controller", func() {
 		tc.externalSecret.Spec.Data = nil
 		tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
 			{
-				Key: remoteKey,
+				Extract: esv1alpha1.ExternalSecretExtract{
+					Key: remoteKey,
+				},
 			},
 		}
 		fakeProvider.WithGetSecretMap(map[string][]byte{
@@ -675,7 +681,9 @@ var _ = Describe("ExternalSecret controller", func() {
 
 		tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
 			{
-				Key: remoteKey,
+				Extract: esv1alpha1.ExternalSecretExtract{
+					Key: remoteKey,
+				},
 			},
 		}
 		fakeProvider.WithGetSecretMap(map[string][]byte{

+ 3 - 3
pkg/provider/akeyless/akeyless.go

@@ -115,13 +115,13 @@ func (a *Akeyless) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretD
 		return nil, err
 	}
 	version := int32(0)
-	if ref.Version != "" {
-		i, err := strconv.ParseInt(ref.Version, 10, 32)
+	if ref.Extract.Version != "" {
+		i, err := strconv.ParseInt(ref.Extract.Version, 10, 32)
 		if err == nil {
 			version = int32(i)
 		}
 	}
-	value, err := a.Client.GetSecretByType(ref.Key, token, version)
+	value, err := a.Client.GetSecretByType(ref.Extract.Key, token, version)
 	if err != nil {
 		return nil, err
 	}

+ 4 - 2
pkg/provider/akeyless/akeyless_test.go

@@ -51,8 +51,10 @@ func makeValidAkeylessTestCase() *akeylessTestCase {
 
 func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
 	return &esv1alpha1.ExternalSecretDataRemoteRef{
-		Key:     "test-secret",
-		Version: "1",
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     "test-secret",
+			Version: "1",
+		},
 	}
 }
 

+ 7 - 7
pkg/provider/alibaba/kms.go

@@ -116,26 +116,26 @@ func (kms *KeyManagementService) GetSecret(ctx context.Context, ref esv1alpha1.E
 		return nil, fmt.Errorf(errUninitalizedAlibabaProvider)
 	}
 	kmsRequest := kmssdk.CreateGetSecretValueRequest()
-	kmsRequest.VersionId = ref.Version
-	kmsRequest.SecretName = ref.Key
+	kmsRequest.VersionId = ref.Extract.Version
+	kmsRequest.SecretName = ref.Extract.Key
 	kmsRequest.SetScheme("https")
 	secretOut, err := kms.Client.GetSecretValue(kmsRequest)
 	if err != nil {
 		return nil, util.SanitizeErr(err)
 	}
-	if ref.Property == "" {
+	if ref.Extract.Property == "" {
 		if secretOut.SecretData != "" {
 			return []byte(secretOut.SecretData), nil
 		}
-		return nil, fmt.Errorf("invalid secret received. no secret string nor binary for key: %s", ref.Key)
+		return nil, fmt.Errorf("invalid secret received. no secret string nor binary for key: %s", ref.Extract.Key)
 	}
 	var payload string
 	if secretOut.SecretData != "" {
 		payload = secretOut.SecretData
 	}
-	val := gjson.Get(payload, ref.Property)
+	val := gjson.Get(payload, ref.Extract.Property)
 	if !val.Exists() {
-		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
+		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
 	}
 	return []byte(val.String()), nil
 }
@@ -156,7 +156,7 @@ func (kms *KeyManagementService) GetSecretMap(ctx context.Context, ref esv1alpha
 	kv := make(map[string]string)
 	err = json.Unmarshal(data, &kv)
 	if err != nil {
-		return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Key, err)
+		return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Extract.Key, err)
 	}
 	secretData := make(map[string][]byte)
 	for k, v := range kv {

+ 4 - 2
pkg/provider/alibaba/kms_test.go

@@ -62,7 +62,9 @@ func makeValidKMSTestCase() *keyManagementServiceTestCase {
 
 func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
 	return &esv1alpha1.ExternalSecretDataRemoteRef{
-		Key: secretName,
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key: secretName,
+		},
 	}
 }
 
@@ -127,7 +129,7 @@ func TestAlibabaKMSGetSecret(t *testing.T) {
 	// good case: custom version set
 	setCustomKey := func(kmstc *keyManagementServiceTestCase) {
 		kmstc.apiOutput.SecretName = "test-example-other"
-		kmstc.ref.Key = "test-example-other"
+		kmstc.ref.Extract.Key = "test-example-other"
 		kmstc.apiOutput.SecretData = secretValue
 		kmstc.expectedSecret = secretValue
 	}

+ 8 - 8
pkg/provider/aws/parameterstore/parameterstore.go

@@ -50,23 +50,23 @@ func New(sess client.ConfigProvider) (*ParameterStore, error) {
 
 // GetSecret returns a single secret from the provider.
 func (pm *ParameterStore) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
-	log.Info("fetching secret value", "key", ref.Key)
+	log.Info("fetching secret value", "key", ref.Extract.Key)
 	out, err := pm.client.GetParameter(&ssm.GetParameterInput{
-		Name:           &ref.Key,
+		Name:           &ref.Extract.Key,
 		WithDecryption: aws.Bool(true),
 	})
 	if err != nil {
 		return nil, util.SanitizeErr(err)
 	}
-	if ref.Property == "" {
+	if ref.Extract.Property == "" {
 		if out.Parameter.Value != nil {
 			return []byte(*out.Parameter.Value), nil
 		}
-		return nil, fmt.Errorf("invalid secret received. parameter value is nil for key: %s", ref.Key)
+		return nil, fmt.Errorf("invalid secret received. parameter value is nil for key: %s", ref.Extract.Key)
 	}
-	val := gjson.Get(*out.Parameter.Value, ref.Property)
+	val := gjson.Get(*out.Parameter.Value, ref.Extract.Property)
 	if !val.Exists() {
-		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
+		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
 	}
 	return []byte(val.String()), nil
 }
@@ -80,7 +80,7 @@ func (pm *ParameterStore) GetAllSecrets(ctx context.Context, ref esv1alpha1.Exte
 
 // GetSecretMap returns multiple k/v pairs from the provider.
 func (pm *ParameterStore) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
-	log.Info("fetching secret map", "key", ref.Key)
+	log.Info("fetching secret map", "key", ref.Extract.Key)
 	data, err := pm.GetSecret(ctx, ref)
 	if err != nil {
 		return nil, err
@@ -88,7 +88,7 @@ func (pm *ParameterStore) GetSecretMap(ctx context.Context, ref esv1alpha1.Exter
 	kv := make(map[string]string)
 	err = json.Unmarshal(data, &kv)
 	if err != nil {
-		return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Key, err)
+		return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Extract.Key, err)
 	}
 	secretData := make(map[string][]byte)
 	for k, v := range kv {

+ 6 - 4
pkg/provider/aws/parameterstore/parameterstore_test.go

@@ -68,7 +68,9 @@ func makeValidAPIOutput() *ssm.GetParameterOutput {
 
 func makeValidRemoteRef() *esv1alpha1.ExternalSecretDataRemoteRef {
 	return &esv1alpha1.ExternalSecretDataRemoteRef{
-		Key: "/baz",
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key: "/baz",
+		},
 	}
 }
 
@@ -94,20 +96,20 @@ func TestGetSecret(t *testing.T) {
 	setExtractProperty := func(pstc *parameterstoreTestCase) {
 		pstc.apiOutput.Parameter.Value = aws.String(`{"/shmoo": "bang"}`)
 		pstc.expectedSecret = "bang"
-		pstc.remoteRef.Property = "/shmoo"
+		pstc.remoteRef.Extract.Property = "/shmoo"
 	}
 
 	// bad case: missing property
 	setMissingProperty := func(pstc *parameterstoreTestCase) {
 		pstc.apiOutput.Parameter.Value = aws.String(`{"/shmoo": "bang"}`)
-		pstc.remoteRef.Property = "INVALPROP"
+		pstc.remoteRef.Extract.Property = "INVALPROP"
 		pstc.expectError = "key INVALPROP does not exist in secret"
 	}
 
 	// bad case: extract property failure due to invalid json
 	setPropertyFail := func(pstc *parameterstoreTestCase) {
 		pstc.apiOutput.Parameter.Value = aws.String(`------`)
-		pstc.remoteRef.Property = "INVALPROP"
+		pstc.remoteRef.Extract.Property = "INVALPROP"
 		pstc.expectError = "key INVALPROP does not exist in secret"
 	}
 

+ 12 - 12
pkg/provider/aws/secretsmanager/secretsmanager.go

@@ -52,18 +52,18 @@ func New(sess client.ConfigProvider) (*SecretsManager, error) {
 
 func (sm *SecretsManager) fetch(_ context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (*awssm.GetSecretValueOutput, error) {
 	ver := "AWSCURRENT"
-	if ref.Version != "" {
-		ver = ref.Version
+	if ref.Extract.Version != "" {
+		ver = ref.Extract.Version
 	}
-	log.Info("fetching secret value", "key", ref.Key, "version", ver)
+	log.Info("fetching secret value", "key", ref.Extract.Key, "version", ver)
 
-	cacheKey := fmt.Sprintf("%s#%s", ref.Key, ver)
+	cacheKey := fmt.Sprintf("%s#%s", ref.Extract.Key, ver)
 	if secretOut, found := sm.cache[cacheKey]; found {
-		log.Info("found secret in cache", "key", ref.Key, "version", ver)
+		log.Info("found secret in cache", "key", ref.Extract.Key, "version", ver)
 		return secretOut, nil
 	}
 	secretOut, err := sm.client.GetSecretValue(&awssm.GetSecretValueInput{
-		SecretId:     &ref.Key,
+		SecretId:     &ref.Extract.Key,
 		VersionStage: &ver,
 	})
 	if err != nil {
@@ -80,14 +80,14 @@ func (sm *SecretsManager) GetSecret(ctx context.Context, ref esv1alpha1.External
 	if err != nil {
 		return nil, util.SanitizeErr(err)
 	}
-	if ref.Property == "" {
+	if ref.Extract.Property == "" {
 		if secretOut.SecretString != nil {
 			return []byte(*secretOut.SecretString), nil
 		}
 		if secretOut.SecretBinary != nil {
 			return secretOut.SecretBinary, nil
 		}
-		return nil, fmt.Errorf("invalid secret received. no secret string nor binary for key: %s", ref.Key)
+		return nil, fmt.Errorf("invalid secret received. no secret string nor binary for key: %s", ref.Extract.Key)
 	}
 	var payload string
 	if secretOut.SecretString != nil {
@@ -97,16 +97,16 @@ func (sm *SecretsManager) GetSecret(ctx context.Context, ref esv1alpha1.External
 		payload = string(secretOut.SecretBinary)
 	}
 
-	val := gjson.Get(payload, ref.Property)
+	val := gjson.Get(payload, ref.Extract.Property)
 	if !val.Exists() {
-		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
+		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
 	}
 	return []byte(val.String()), nil
 }
 
 // GetSecretMap returns multiple k/v pairs from the provider.
 func (sm *SecretsManager) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
-	log.Info("fetching secret map", "key", ref.Key)
+	log.Info("fetching secret map", "key", ref.Extract.Key)
 	data, err := sm.GetSecret(ctx, ref)
 	if err != nil {
 		return nil, err
@@ -114,7 +114,7 @@ func (sm *SecretsManager) GetSecretMap(ctx context.Context, ref esv1alpha1.Exter
 	kv := make(map[string]json.RawMessage)
 	err = json.Unmarshal(data, &kv)
 	if err != nil {
-		return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Key, err)
+		return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Extract.Key, err)
 	}
 	secretData := make(map[string][]byte)
 	for k, v := range kv {

+ 13 - 11
pkg/provider/aws/secretsmanager/secretsmanager_test.go

@@ -61,8 +61,10 @@ func makeValidSecretsManagerTestCase() *secretsManagerTestCase {
 
 func makeValidRemoteRef() *esv1alpha1.ExternalSecretDataRemoteRef {
 	return &esv1alpha1.ExternalSecretDataRemoteRef{
-		Key:     "/baz",
-		Version: "AWSCURRENT",
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     "/baz",
+			Version: "AWSCURRENT",
+		},
 	}
 }
 
@@ -108,20 +110,20 @@ func TestSecretsManagerGetSecret(t *testing.T) {
 	// good case: extract property
 	// Testing that the property exists in the SecretString
 	setRemoteRefPropertyExistsInKey := func(smtc *secretsManagerTestCase) {
-		smtc.remoteRef.Property = "/shmoo"
+		smtc.remoteRef.Extract.Property = "/shmoo"
 		smtc.apiOutput.SecretString = aws.String(`{"/shmoo": "bang"}`)
 		smtc.expectedSecret = "bang"
 	}
 
 	// bad case: missing property
 	setRemoteRefMissingProperty := func(smtc *secretsManagerTestCase) {
-		smtc.remoteRef.Property = "INVALPROP"
+		smtc.remoteRef.Extract.Property = "INVALPROP"
 		smtc.expectError = "key INVALPROP does not exist in secret"
 	}
 
 	// bad case: extract property failure due to invalid json
 	setRemoteRefMissingPropertyInvalidJSON := func(smtc *secretsManagerTestCase) {
-		smtc.remoteRef.Property = "INVALPROP"
+		smtc.remoteRef.Extract.Property = "INVALPROP"
 		smtc.apiOutput.SecretString = aws.String(`------`)
 		smtc.expectError = "key INVALPROP does not exist in secret"
 	}
@@ -144,14 +146,14 @@ func TestSecretsManagerGetSecret(t *testing.T) {
 	setNestedSecretValueJSONParsing := func(smtc *secretsManagerTestCase) {
 		smtc.apiOutput.SecretString = nil
 		smtc.apiOutput.SecretBinary = []byte(`{"foobar":{"baz":"nestedval"}}`)
-		smtc.remoteRef.Property = "foobar.baz"
+		smtc.remoteRef.Extract.Property = "foobar.baz"
 		smtc.expectedSecret = "nestedval"
 	}
 
 	// good case: custom version set
 	setCustomVersion := func(smtc *secretsManagerTestCase) {
 		smtc.apiInput.VersionStage = aws.String("1234")
-		smtc.remoteRef.Version = "1234"
+		smtc.remoteRef.Extract.Version = "1234"
 		smtc.apiOutput.SecretString = aws.String("FOOBA!")
 		smtc.expectedSecret = "FOOBA!"
 	}
@@ -190,26 +192,26 @@ func TestCaching(t *testing.T) {
 	// over 1
 	firstCall := func(smtc *secretsManagerTestCase) {
 		smtc.apiOutput.SecretString = aws.String(`{"foo":"bar", "bar":"vodka"}`)
-		smtc.remoteRef.Property = "foo"
+		smtc.remoteRef.Extract.Property = "foo"
 		smtc.expectedSecret = "bar"
 		smtc.expectedCounter = aws.Int(1)
 		smtc.fakeClient = fakeClient
 	}
 	secondCall := func(smtc *secretsManagerTestCase) {
 		smtc.apiOutput.SecretString = aws.String(`{"foo":"bar", "bar":"vodka"}`)
-		smtc.remoteRef.Property = "bar"
+		smtc.remoteRef.Extract.Property = "bar"
 		smtc.expectedSecret = "vodka"
 		smtc.expectedCounter = aws.Int(1)
 		smtc.fakeClient = fakeClient
 	}
 	notCachedCall := func(smtc *secretsManagerTestCase) {
 		smtc.apiOutput.SecretString = aws.String(`{"sheldon":"bazinga", "bar":"foo"}`)
-		smtc.remoteRef.Property = "sheldon"
+		smtc.remoteRef.Extract.Property = "sheldon"
 		smtc.expectedSecret = "bazinga"
 		smtc.expectedCounter = aws.Int(2)
 		smtc.fakeClient = fakeClient
 		smtc.apiInput.SecretId = aws.String("xyz")
-		smtc.remoteRef.Key = "xyz" // it should reset the cache since the key is different
+		smtc.remoteRef.Extract.Key = "xyz" // it should reset the cache since the key is different
 	}
 
 	cachedCases := []*secretsManagerTestCase{

+ 10 - 10
pkg/provider/azure/keyvault/keyvault.go

@@ -99,8 +99,8 @@ func (a *Azure) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretData
 		return nil, fmt.Errorf("%s name cannot be empty", objectType)
 	}
 
-	if ref.Version != "" {
-		version = ref.Version
+	if ref.Extract.Version != "" {
+		version = ref.Extract.Version
 	}
 
 	switch objectType {
@@ -111,12 +111,12 @@ func (a *Azure) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretData
 		if err != nil {
 			return nil, err
 		}
-		if ref.Property == "" {
+		if ref.Extract.Property == "" {
 			return []byte(*secretResp.Value), nil
 		}
-		res := gjson.Get(*secretResp.Value, ref.Property)
+		res := gjson.Get(*secretResp.Value, ref.Extract.Property)
 		if !res.Exists() {
-			return nil, fmt.Errorf("property %s does not exist in key %s", ref.Property, ref.Key)
+			return nil, fmt.Errorf("property %s does not exist in key %s", ref.Extract.Property, ref.Extract.Key)
 		}
 		return []byte(res.String()), err
 	case "cert":
@@ -179,8 +179,8 @@ func (a *Azure) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretD
 func (a *Azure) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
 	basicClient := a.baseClient
 	secretsMap := make(map[string][]byte)
-	checkTags := len(ref.Tags) > 0
-	checkName := len(ref.RegExp) > 0
+	checkTags := len(ref.Find.Tags) > 0
+	checkName := len(ref.Find.Name.RegExp) > 0
 
 	secretListIter, err := basicClient.GetSecretsComplete(context.Background(), a.vaultURL, nil)
 
@@ -219,13 +219,13 @@ func (a *Azure) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecret
 }
 
 func okByName(ref esv1alpha1.ExternalSecretDataRemoteRef, secretName string) bool {
-	matches, _ := regexp.MatchString(ref.RegExp, secretName)
+	matches, _ := regexp.MatchString(ref.Find.Name.RegExp, secretName)
 	return matches
 }
 
 func okByTags(ref esv1alpha1.ExternalSecretDataRemoteRef, secret keyvault.SecretItem) bool {
 	tagsFound := true
-	for k, v := range ref.Tags {
+	for k, v := range ref.Find.Tags {
 		if val, ok := secret.Tags[k]; !ok || *val != v {
 			tagsFound = false
 			break
@@ -333,7 +333,7 @@ func (a *Azure) Close(ctx context.Context) error {
 func getObjType(ref esv1alpha1.ExternalSecretDataRemoteRef) (string, string) {
 	objectType := defaultObjType
 
-	secretName := ref.Key
+	secretName := ref.Extract.Key
 	nameSplitted := strings.Split(secretName, "/")
 
 	if len(nameSplitted) > 1 {

+ 33 - 41
pkg/provider/azure/keyvault/keyvault_test.go

@@ -30,7 +30,7 @@ import (
 	v1 "github.com/external-secrets/external-secrets/apis/meta/v1"
 	fake "github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault/fake"
 	"github.com/external-secrets/external-secrets/pkg/provider/schema"
-	utils "github.com/external-secrets/external-secrets/pkg/utils"
+	"github.com/external-secrets/external-secrets/pkg/utils"
 )
 
 type secretManagerTestCase struct {
@@ -187,7 +187,7 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
 	}
 
 	badNoNameSecret := func(smtc *secretManagerTestCase) {
-		smtc.ref.Key = ""
+		smtc.ref.Extract.Key = ""
 		smtc.expectedSecret = ""
 		smtc.secretName = "secret/"
 		smtc.expectError = fmt.Sprintf("%s name cannot be empty", "secret")
@@ -198,8 +198,8 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
 		smtc.secretOutput = keyvault.SecretBundle{
 			Value: &secretString,
 		}
-		smtc.ref.Version = "v1"
-		smtc.secretVersion = smtc.ref.Version
+		smtc.ref.Extract.Version = "v1"
+		smtc.secretVersion = smtc.ref.Extract.Version
 	}
 
 	setSecretWithProperty := func(smtc *secretManagerTestCase) {
@@ -208,7 +208,7 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
 		smtc.secretOutput = keyvault.SecretBundle{
 			Value: &jsonString,
 		}
-		smtc.ref.Property = "Name"
+		smtc.ref.Extract.Property = "Name"
 	}
 
 	badSecretWithProperty := func(smtc *secretManagerTestCase) {
@@ -217,8 +217,8 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
 		smtc.secretOutput = keyvault.SecretBundle{
 			Value: &jsonString,
 		}
-		smtc.ref.Property = "Age"
-		smtc.expectError = fmt.Sprintf("property %s does not exist in key %s", smtc.ref.Property, smtc.ref.Key)
+		smtc.ref.Extract.Property = "Age"
+		smtc.expectError = fmt.Sprintf("property %s does not exist in key %s", smtc.ref.Extract.Property, smtc.ref.Extract.Key)
 		smtc.apiErr = fmt.Errorf(smtc.expectError)
 	}
 
@@ -229,7 +229,7 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
 		smtc.keyOutput = keyvault.KeyBundle{
 			Key: newKVJWK([]byte(jwkPubRSA)),
 		}
-		smtc.ref.Key = smtc.secretName
+		smtc.ref.Extract.Key = smtc.secretName
 	}
 
 	// // good case: key set
@@ -239,7 +239,7 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
 		smtc.keyOutput = keyvault.KeyBundle{
 			Key: newKVJWK([]byte(jwkPubEC)),
 		}
-		smtc.ref.Key = smtc.secretName
+		smtc.ref.Extract.Key = smtc.secretName
 	}
 
 	// // good case: key set
@@ -250,14 +250,14 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
 		smtc.certOutput = keyvault.CertificateBundle{
 			Cer: &byteArrString,
 		}
-		smtc.ref.Key = smtc.secretName
+		smtc.ref.Extract.Key = smtc.secretName
 	}
 
 	badSecretType := func(smtc *secretManagerTestCase) {
 		smtc.secretName = "name"
 		smtc.expectedSecret = ""
 		smtc.expectError = fmt.Sprintf("unknown Azure Keyvault object Type for %s", smtc.secretName)
-		smtc.ref.Key = fmt.Sprintf("dummy/%s", smtc.secretName)
+		smtc.ref.Extract.Key = fmt.Sprintf("dummy/%s", smtc.secretName)
 	}
 
 	successCases := []*secretManagerTestCase{
@@ -312,7 +312,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
 		smtc.secretOutput = keyvault.SecretBundle{
 			Value: &jsonString,
 		}
-		smtc.ref.Property = "Address"
+		smtc.ref.Extract.Property = "Address"
 
 		smtc.expectedData["Street"] = []byte("Myroad st.")
 		smtc.expectedData["CP"] = []byte("J4K4T4")
@@ -324,8 +324,8 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
 		smtc.secretOutput = keyvault.SecretBundle{
 			Value: &jsonString,
 		}
-		smtc.ref.Property = "Age"
-		smtc.expectError = fmt.Sprintf("property %s does not exist in key %s", smtc.ref.Property, smtc.ref.Key)
+		smtc.ref.Extract.Property = "Age"
+		smtc.expectError = fmt.Sprintf("property %s does not exist in key %s", smtc.ref.Extract.Property, smtc.ref.Extract.Key)
 		smtc.apiErr = fmt.Errorf(smtc.expectError)
 	}
 
@@ -335,7 +335,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
 		smtc.keyOutput = keyvault.KeyBundle{
 			Key: newKVJWK([]byte(jwkPubRSA)),
 		}
-		smtc.ref.Key = smtc.secretName
+		smtc.ref.Extract.Key = smtc.secretName
 		smtc.expectError = "cannot get use dataFrom to get key secret"
 	}
 
@@ -346,7 +346,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
 		smtc.certOutput = keyvault.CertificateBundle{
 			Cer: &byteArrString,
 		}
-		smtc.ref.Key = smtc.secretName
+		smtc.ref.Extract.Key = smtc.secretName
 		smtc.expectError = "cannot get use dataFrom to get certificate secret"
 	}
 
@@ -354,7 +354,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
 		smtc.secretName = "name"
 		smtc.expectedSecret = ""
 		smtc.expectError = fmt.Sprintf("unknown Azure Keyvault object Type for %s", smtc.secretName)
-		smtc.ref.Key = fmt.Sprintf("dummy/%s", smtc.secretName)
+		smtc.ref.Extract.Key = fmt.Sprintf("dummy/%s", smtc.secretName)
 	}
 
 	successCases := []*secretManagerTestCase{
@@ -382,6 +382,12 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
 
 func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
 	secretString := "changedvalue"
+	secretName := "example-1"
+	wrongName := "not-valid"
+	environment := "dev"
+	author := "seb"
+	regexp := "^example"
+	enabled := true
 
 	getNextPage := func(ctx context.Context, list keyvault.SecretListResult) (result keyvault.SecretListResult, err error) {
 		return keyvault.SecretListResult{
@@ -391,10 +397,7 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
 	}
 
 	setOneSecretByName := func(smtc *secretManagerTestCase) {
-
-		smtc.ref.RegExp = "^example"
-		secretName := "example-1"
-		enabled := true
+		smtc.ref.Find.Name.RegExp = regexp
 		enabledAtt := keyvault.SecretAttributes{
 			Enabled: &enabled,
 		}
@@ -422,11 +425,7 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
 	}
 
 	setTwoSecretsByName := func(smtc *secretManagerTestCase) {
-
-		smtc.ref.RegExp = "^example"
-		secretName := "example-1"
-		wrongName := "not-valid"
-		enabled := true
+		smtc.ref.Find.Name.RegExp = regexp
 		enabledAtt := keyvault.SecretAttributes{
 			Enabled: &enabled,
 		}
@@ -460,11 +459,6 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
 	}
 
 	setOneSecretByTag := func(smtc *secretManagerTestCase) {
-
-		secretName := "example-1"
-		environment := "dev"
-
-		enabled := true
 		enabledAtt := keyvault.SecretAttributes{
 			Enabled: &enabled,
 		}
@@ -488,16 +482,12 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
 		smtc.secretOutput = keyvault.SecretBundle{
 			Value: &secretString,
 		}
-		smtc.ref.Tags = map[string]string{"environment": environment}
+		smtc.ref.Find.Tags = map[string]string{"environment": environment}
 
-		smtc.expectedData["example-1"] = []byte(secretString)
+		smtc.expectedData[secretName] = []byte(secretString)
 	}
 
 	setTwoSecretsByTag := func(smtc *secretManagerTestCase) {
-
-		secretName := "example-1"
-		environment := "dev"
-		author := "seb"
 		enabled := true
 		enabledAtt := keyvault.SecretAttributes{
 			Enabled: &enabled,
@@ -522,9 +512,9 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
 		smtc.secretOutput = keyvault.SecretBundle{
 			Value: &secretString,
 		}
-		smtc.ref.Tags = map[string]string{"environment": environment, "author": author}
+		smtc.ref.Find.Tags = map[string]string{"environment": environment, "author": author}
 
-		smtc.expectedData["example-1"] = []byte(secretString)
+		smtc.expectedData[secretName] = []byte(secretString)
 	}
 
 	successCases := []*secretManagerTestCase{
@@ -549,7 +539,9 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
 
 func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
 	return &esv1alpha1.ExternalSecretDataRemoteRef{
-		Key:     "test-secret",
-		Version: "default",
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     "test-secret",
+			Version: "default",
+		},
 	}
 }

+ 6 - 6
pkg/provider/gcp/secretmanager/secretsmanager.go

@@ -167,24 +167,24 @@ func (sm *ProviderGCP) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSec
 		return nil, fmt.Errorf(errUninitalizedGCPProvider)
 	}
 
-	version := ref.Version
+	version := ref.Extract.Version
 	if version == "" {
 		version = defaultVersion
 	}
 
 	req := &secretmanagerpb.AccessSecretVersionRequest{
-		Name: fmt.Sprintf("projects/%s/secrets/%s/versions/%s", sm.projectID, ref.Key, version),
+		Name: fmt.Sprintf("projects/%s/secrets/%s/versions/%s", sm.projectID, ref.Extract.Key, version),
 	}
 	result, err := sm.SecretManagerClient.AccessSecretVersion(ctx, req)
 	if err != nil {
 		return nil, fmt.Errorf(errClientGetSecretAccess, err)
 	}
 
-	if ref.Property == "" {
+	if ref.Extract.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 nil, fmt.Errorf("invalid secret received. no secret string for key: %s", ref.Extract.Key)
 	}
 
 	var payload string
@@ -192,9 +192,9 @@ func (sm *ProviderGCP) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSec
 		payload = string(result.Payload.Data)
 	}
 
-	val := gjson.Get(payload, ref.Property)
+	val := gjson.Get(payload, ref.Extract.Property)
 	if !val.Exists() {
-		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
+		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
 	}
 	return []byte(val.String()), nil
 }

+ 10 - 6
pkg/provider/gcp/secretmanager/secretsmanager_test.go

@@ -58,8 +58,10 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
 
 func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
 	return &esv1alpha1.ExternalSecretDataRemoteRef{
-		Key:     "/baz",
-		Version: "default",
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     "/baz",
+			Version: "default",
+		},
 	}
 }
 
@@ -111,9 +113,11 @@ func TestSecretManagerGetSecret(t *testing.T) {
 	// good case: ref with
 	setCustomRef := func(smtc *secretManagerTestCase) {
 		smtc.ref = &esv1alpha1.ExternalSecretDataRemoteRef{
-			Key:      "/baz",
-			Version:  "default",
-			Property: "name.first",
+			Extract: esv1alpha1.ExternalSecretExtract{
+				Key:      "/baz",
+				Version:  "default",
+				Property: "name.first",
+			},
 		}
 		smtc.apiInput.Name = "projects/default/secrets//baz/versions/default"
 		smtc.apiOutput.Payload.Data = []byte(
@@ -130,7 +134,7 @@ func TestSecretManagerGetSecret(t *testing.T) {
 
 	// good case: custom version set
 	setCustomVersion := func(smtc *secretManagerTestCase) {
-		smtc.ref.Version = "1234"
+		smtc.ref.Extract.Version = "1234"
 		smtc.apiInput.Name = "projects/default/secrets//baz/versions/1234"
 		smtc.apiOutput.Payload.Data = []byte("FOOBA!")
 		smtc.expectedSecret = "FOOBA!"

+ 7 - 7
pkg/provider/gitlab/gitlab.go

@@ -153,7 +153,7 @@ func (g *Gitlab) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDat
 		return nil, fmt.Errorf(errUninitalizedGitlabProvider)
 	}
 	// Need to replace hyphens with underscores to work with Gitlab API
-	ref.Key = strings.ReplaceAll(ref.Key, "-", "_")
+	ref.Extract.Key = strings.ReplaceAll(ref.Extract.Key, "-", "_")
 	// Retrieves a gitlab variable in the form
 	// {
 	// 	"key": "TEST_VARIABLE_1",
@@ -161,16 +161,16 @@ func (g *Gitlab) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDat
 	// 	"value": "TEST_1",
 	// 	"protected": false,
 	// 	"masked": true
-	data, _, err := g.client.GetVariable(g.projectID, ref.Key, nil) // Optional 'filter' parameter could be added later
+	data, _, err := g.client.GetVariable(g.projectID, ref.Extract.Key, nil) // Optional 'filter' parameter could be added later
 	if err != nil {
 		return nil, err
 	}
 
-	if ref.Property == "" {
+	if ref.Extract.Property == "" {
 		if data.Value != "" {
 			return []byte(data.Value), nil
 		}
-		return nil, fmt.Errorf("invalid secret received. no secret string for key: %s", ref.Key)
+		return nil, fmt.Errorf("invalid secret received. no secret string for key: %s", ref.Extract.Key)
 	}
 
 	var payload string
@@ -178,9 +178,9 @@ func (g *Gitlab) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDat
 		payload = data.Value
 	}
 
-	val := gjson.Get(payload, ref.Property)
+	val := gjson.Get(payload, ref.Extract.Property)
 	if !val.Exists() {
-		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
+		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
 	}
 	return []byte(val.String()), nil
 }
@@ -196,7 +196,7 @@ func (g *Gitlab) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecret
 	// Gets a secret as normal, expecting secret value to be a json object
 	data, err := g.GetSecret(ctx, ref)
 	if err != nil {
-		return nil, fmt.Errorf("error getting secret %s: %w", ref.Key, err)
+		return nil, fmt.Errorf("error getting secret %s: %w", ref.Extract.Key, err)
 	}
 
 	// Maps the json data to a string:string map

+ 4 - 2
pkg/provider/gitlab/gitlab_test.go

@@ -59,8 +59,10 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
 
 func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
 	return &esv1alpha1.ExternalSecretDataRemoteRef{
-		Key:     "test-secret",
-		Version: "default",
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     "test-secret",
+			Version: "default",
+		},
 	}
 }
 

+ 10 - 10
pkg/provider/ibm/provider.go

@@ -106,7 +106,7 @@ func (ibm *providerIBM) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSe
 	}
 
 	secretType := sm.GetSecretOptionsSecretTypeArbitraryConst
-	secretName := ref.Key
+	secretName := ref.Extract.Key
 	nameSplitted := strings.Split(secretName, "/")
 
 	if len(nameSplitted) > 1 {
@@ -121,7 +121,7 @@ func (ibm *providerIBM) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSe
 
 	case sm.CreateSecretOptionsSecretTypeUsernamePasswordConst:
 
-		if ref.Property == "" {
+		if ref.Extract.Property == "" {
 			return nil, fmt.Errorf("remoteRef.property required for secret type username_password")
 		}
 		return getUsernamePasswordSecret(ibm, &secretName, ref)
@@ -132,8 +132,8 @@ func (ibm *providerIBM) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSe
 
 	case sm.CreateSecretOptionsSecretTypeImportedCertConst:
 
-		if ref.Property == "" {
-			return nil, fmt.Errorf("remoteRef.property required for secret type imported_cert")
+		if ref.Extract.Property == "" {
+			return nil, fmt.Errorf("remoteRef.Extract.property required for secret type imported_cert")
 		}
 
 		return getImportCertSecret(ibm, &secretName, ref)
@@ -171,10 +171,10 @@ func getImportCertSecret(ibm *providerIBM, secretName *string, ref esv1alpha1.Ex
 	secret := response.Resources[0].(*sm.SecretResource)
 	secretData := secret.SecretData.(map[string]interface{})
 
-	if val, ok := secretData[ref.Property]; ok {
+	if val, ok := secretData[ref.Extract.Property]; ok {
 		return []byte(val.(string)), nil
 	}
-	return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
+	return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
 }
 
 func getIamCredentialsSecret(ibm *providerIBM, secretName *string) ([]byte, error) {
@@ -206,10 +206,10 @@ func getUsernamePasswordSecret(ibm *providerIBM, secretName *string, ref esv1alp
 	secret := response.Resources[0].(*sm.SecretResource)
 	secretData := secret.SecretData.(map[string]interface{})
 
-	if val, ok := secretData[ref.Property]; ok {
+	if val, ok := secretData[ref.Extract.Property]; ok {
 		return []byte(val.(string)), nil
 	}
-	return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
+	return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
 }
 
 func (ibm *providerIBM) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
@@ -218,7 +218,7 @@ func (ibm *providerIBM) GetSecretMap(ctx context.Context, ref esv1alpha1.Externa
 	}
 
 	secretType := sm.GetSecretOptionsSecretTypeArbitraryConst
-	secretName := ref.Key
+	secretName := ref.Extract.Key
 	nameSplitted := strings.Split(secretName, "/")
 
 	if len(nameSplitted) > 1 {
@@ -231,7 +231,7 @@ func (ibm *providerIBM) GetSecretMap(ctx context.Context, ref esv1alpha1.Externa
 		response, _, err := ibm.IBMClient.GetSecret(
 			&sm.GetSecretOptions{
 				SecretType: core.StringPtr(sm.GetSecretOptionsSecretTypeArbitraryConst),
-				ID:         &ref.Key,
+				ID:         &ref.Extract.Key,
 			})
 		if err != nil {
 			return nil, err

+ 16 - 14
pkg/provider/ibm/provider_test.go

@@ -63,8 +63,10 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
 
 func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
 	return &esv1alpha1.ExternalSecretDataRemoteRef{
-		Key:     "test-secret",
-		Version: "default",
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     "test-secret",
+			Version: "default",
+		},
 	}
 }
 
@@ -146,7 +148,7 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 				Name:       utilpointer.StringPtr("testyname"),
 				SecretData: secretData,
 			}}
-		smtc.ref.Key = "testyname"
+		smtc.ref.Extract.Key = "testyname"
 		smtc.apiInput.ID = utilpointer.StringPtr("testyname")
 		smtc.apiOutput.Resources = resources
 		smtc.expectedSecret = secretString
@@ -164,7 +166,7 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 
 		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
 		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = secretUserPass
+		smtc.ref.Extract.Key = secretUserPass
 		smtc.expectError = "remoteRef.property required for secret type username_password"
 	}
 
@@ -179,8 +181,8 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 
 		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
 		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = secretUserPass
-		smtc.ref.Property = "password"
+		smtc.ref.Extract.Key = secretUserPass
+		smtc.ref.Extract.Property = "password"
 		smtc.expectedSecret = secretPassword
 	}
 
@@ -195,7 +197,7 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 
 		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst)
 		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = "iam_credentials/test-secret"
+		smtc.ref.Extract.Key = "iam_credentials/test-secret"
 		smtc.expectedSecret = secretAPIKey
 	}
 
@@ -211,8 +213,8 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 
 		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst)
 		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = secretCert
-		smtc.ref.Property = "certificate"
+		smtc.ref.Extract.Key = secretCert
+		smtc.ref.Extract.Property = "certificate"
 		smtc.expectedSecret = secretCertificate
 	}
 
@@ -227,8 +229,8 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 
 		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst)
 		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = secretCert
-		smtc.expectError = "remoteRef.property required for secret type imported_cert"
+		smtc.ref.Extract.Key = secretCert
+		smtc.expectError = "remoteRef.Extract.property required for secret type imported_cert"
 	}
 
 	successCases := []*secretManagerTestCase{
@@ -311,7 +313,7 @@ func TestGetSecretMap(t *testing.T) {
 
 		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
 		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = "username_password/test-secret"
+		smtc.ref.Extract.Key = "username_password/test-secret"
 		smtc.expectedData["username"] = []byte(secretUsername)
 		smtc.expectedData["password"] = []byte(secretPassword)
 	}
@@ -327,7 +329,7 @@ func TestGetSecretMap(t *testing.T) {
 
 		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst)
 		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = "iam_credentials/test-secret"
+		smtc.ref.Extract.Key = "iam_credentials/test-secret"
 		smtc.expectedData["apikey"] = []byte(secretAPIKey)
 	}
 
@@ -347,7 +349,7 @@ func TestGetSecretMap(t *testing.T) {
 
 		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst)
 		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = "imported_cert/test-secret"
+		smtc.ref.Extract.Key = "imported_cert/test-secret"
 		smtc.expectedData["certificate"] = []byte(secretCertificate)
 		smtc.expectedData["private_key"] = []byte(secretPrivateKey)
 		smtc.expectedData["intermediate"] = []byte(secretIntermediate)

+ 5 - 5
pkg/provider/oracle/oracle.go

@@ -132,8 +132,8 @@ func (vms *VaultManagementService) GetSecret(ctx context.Context, ref esv1alpha1
 
 	sec, err := vms.Client.GetSecretBundleByName(ctx, secrets.GetSecretBundleByNameRequest{
 		VaultId:    &vms.vault,
-		SecretName: &ref.Key,
-		Stage:      secrets.GetSecretBundleByNameStageEnum(ref.Version),
+		SecretName: &ref.Extract.Key,
+		Stage:      secrets.GetSecretBundleByNameStageEnum(ref.Extract.Version),
 	})
 	if err != nil {
 		return nil, util.SanitizeErr(err)
@@ -149,14 +149,14 @@ func (vms *VaultManagementService) GetSecret(ctx context.Context, ref esv1alpha1
 		return nil, err
 	}
 
-	if ref.Property == "" {
+	if ref.Extract.Property == "" {
 		return payload, nil
 	}
 
-	val := gjson.Get(string(payload), ref.Property)
+	val := gjson.Get(string(payload), ref.Extract.Property)
 
 	if !val.Exists() {
-		return nil, fmt.Errorf(errMissingKey, ref.Key)
+		return nil, fmt.Errorf(errMissingKey, ref.Extract.Key)
 	}
 
 	return []byte(val.String()), nil

+ 4 - 2
pkg/provider/oracle/oracle_test.go

@@ -55,8 +55,10 @@ func makeValidVaultTestCase() *vaultTestCase {
 
 func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
 	return &esv1alpha1.ExternalSecretDataRemoteRef{
-		Key:     "test-secret",
-		Version: "default",
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     "test-secret",
+			Version: "default",
+		},
 	}
 }
 

+ 4 - 4
pkg/provider/vault/vault.go

@@ -148,19 +148,19 @@ func (c *connector) NewClient(ctx context.Context, store esv1alpha1.GenericStore
 }
 
 func (v *client) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
-	data, err := v.readSecret(ctx, ref.Key, ref.Version)
+	data, err := v.readSecret(ctx, ref.Extract.Key, ref.Extract.Version)
 	if err != nil {
 		return nil, err
 	}
-	value, exists := data[ref.Property]
+	value, exists := data[ref.Extract.Property]
 	if !exists {
-		return nil, fmt.Errorf(errSecretKeyFmt, ref.Property)
+		return nil, fmt.Errorf(errSecretKeyFmt, ref.Extract.Property)
 	}
 	return value, nil
 }
 
 func (v *client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
-	return v.readSecret(ctx, ref.Key, ref.Version)
+	return v.readSecret(ctx, ref.Extract.Key, ref.Extract.Version)
 }
 
 // Implements store.Client.GetAllSecrets Interface.

+ 3 - 3
pkg/provider/webhook/webhook.go

@@ -181,9 +181,9 @@ func (w *WebHook) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecre
 func (w *WebHook) getTemplateData(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef, secrets []esv1alpha1.WebhookSecret) (map[string]map[string]string, error) {
 	data := map[string]map[string]string{
 		"remoteRef": {
-			"key":      url.QueryEscape(ref.Key),
-			"version":  url.QueryEscape(ref.Version),
-			"property": url.QueryEscape(ref.Property),
+			"key":      url.QueryEscape(ref.Extract.Key),
+			"version":  url.QueryEscape(ref.Extract.Version),
+			"property": url.QueryEscape(ref.Extract.Property),
 		},
 	}
 	for _, secref := range secrets {

+ 8 - 4
pkg/provider/webhook/webhook_test.go

@@ -270,8 +270,10 @@ func runTestCase(tc testCase, t *testing.T) {
 
 func testGetSecretMap(tc testCase, t *testing.T, client provider.SecretsClient) {
 	testRef := esv1alpha1.ExternalSecretDataRemoteRef{
-		Key:     tc.Args.Key,
-		Version: tc.Args.Version,
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     tc.Args.Key,
+			Version: tc.Args.Version,
+		},
 	}
 	secretmap, err := client.GetSecretMap(context.Background(), testRef)
 	errStr := ""
@@ -295,8 +297,10 @@ func testGetSecretMap(tc testCase, t *testing.T, client provider.SecretsClient)
 
 func testGetSecret(tc testCase, t *testing.T, client provider.SecretsClient) {
 	testRef := esv1alpha1.ExternalSecretDataRemoteRef{
-		Key:     tc.Args.Key,
-		Version: tc.Args.Version,
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     tc.Args.Key,
+			Version: tc.Args.Version,
+		},
 	}
 	secret, err := client.GetSecret(context.Background(), testRef)
 	errStr := ""

+ 4 - 4
pkg/provider/yandex/lockbox/lockbox.go

@@ -226,12 +226,12 @@ type lockboxSecretsClient struct {
 
 // GetSecret returns a single secret from the provider.
 func (c *lockboxSecretsClient) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
-	entries, err := c.lockboxClient.GetPayloadEntries(ctx, c.iamToken, ref.Key, ref.Version)
+	entries, err := c.lockboxClient.GetPayloadEntries(ctx, c.iamToken, ref.Extract.Key, ref.Extract.Version)
 	if err != nil {
 		return nil, fmt.Errorf("unable to request secret payload to get secret: %w", err)
 	}
 
-	if ref.Property == "" {
+	if ref.Extract.Property == "" {
 		keyToValue := make(map[string]interface{}, len(entries))
 		for _, entry := range entries {
 			value, err := getValueAsIs(entry)
@@ -247,7 +247,7 @@ func (c *lockboxSecretsClient) GetSecret(ctx context.Context, ref esv1alpha1.Ext
 		return out, nil
 	}
 
-	entry, err := findEntryByKey(entries, ref.Property)
+	entry, err := findEntryByKey(entries, ref.Extract.Property)
 	if err != nil {
 		return nil, err
 	}
@@ -263,7 +263,7 @@ func (c *lockboxSecretsClient) GetAllSecrets(ctx context.Context, ref esv1alpha1
 
 // GetSecretMap returns multiple k/v pairs from the provider.
 func (c *lockboxSecretsClient) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
-	entries, err := c.lockboxClient.GetPayloadEntries(ctx, c.iamToken, ref.Key, ref.Version)
+	entries, err := c.lockboxClient.GetPayloadEntries(ctx, c.iamToken, ref.Extract.Key, ref.Extract.Version)
 	if err != nil {
 		return nil, fmt.Errorf("unable to request secret payload to get secret map: %w", err)
 	}

+ 150 - 26
pkg/provider/yandex/lockbox/lockbox_test.go

@@ -131,7 +131,11 @@ func TestGetSecretForAllEntries(t *testing.T) {
 	})
 	secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
 	tassert.Nil(t, err)
-	data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID})
+	data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key: secretID,
+		},
+	})
 	tassert.Nil(t, err)
 
 	tassert.Equal(
@@ -169,7 +173,12 @@ func TestGetSecretForTextEntry(t *testing.T) {
 	})
 	secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
 	tassert.Nil(t, err)
-	data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
+	data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID,
+			Property: k1,
+		},
+	})
 	tassert.Nil(t, err)
 
 	tassert.Equal(t, v1, string(data))
@@ -200,7 +209,12 @@ func TestGetSecretForBinaryEntry(t *testing.T) {
 	})
 	secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
 	tassert.Nil(t, err)
-	data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k2})
+	data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID,
+			Property: k2,
+		},
+	})
 	tassert.Nil(t, err)
 
 	tassert.Equal(t, v2, data)
@@ -229,7 +243,12 @@ func TestGetSecretByVersionID(t *testing.T) {
 	})
 	secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
 	tassert.Nil(t, err)
-	data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
+	data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     secretID,
+			Version: oldVersionID,
+		},
+	})
 	tassert.Nil(t, err)
 
 	tassert.Equal(t, map[string]string{oldKey: oldVal}, unmarshalStringMap(t, data))
@@ -239,11 +258,21 @@ func TestGetSecretByVersionID(t *testing.T) {
 		textEntry(newKey, newVal),
 	)
 
-	data, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
+	data, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     secretID,
+			Version: oldVersionID,
+		},
+	})
 	tassert.Nil(t, err)
 	tassert.Equal(t, map[string]string{oldKey: oldVal}, unmarshalStringMap(t, data))
 
-	data, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: newVersionID})
+	data, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     secretID,
+			Version: newVersionID,
+		},
+	})
 	tassert.Nil(t, err)
 	tassert.Equal(t, map[string]string{newKey: newVal}, unmarshalStringMap(t, data))
 }
@@ -271,7 +300,11 @@ func TestGetSecretUnauthorized(t *testing.T) {
 	})
 	secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
 	tassert.Nil(t, err)
-	_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID})
+	_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key: secretID,
+		},
+	})
 	tassert.EqualError(t, err, errSecretPayloadPermissionDenied)
 }
 
@@ -294,13 +327,22 @@ func TestGetSecretNotFound(t *testing.T) {
 	})
 	secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
 	tassert.Nil(t, err)
-	_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: "no-secret-with-this-id"})
+	_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key: "no-secret-with-this-id",
+		},
+	})
 	tassert.EqualError(t, err, errSecretPayloadNotFound)
 
 	secretID, _ := lockboxBackend.CreateSecret(authorizedKey,
 		textEntry("k1", "v1"),
 	)
-	_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: "no-version-with-this-id"})
+	_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     secretID,
+			Version: "no-version-with-this-id",
+		},
+	})
 	tassert.EqualError(t, err, "unable to request secret payload to get secret: version not found")
 }
 
@@ -339,17 +381,37 @@ func TestGetSecretWithTwoNamespaces(t *testing.T) {
 	secretsClient2, err := provider.NewClient(ctx, store2, k8sClient, namespace2)
 	tassert.Nil(t, err)
 
-	data, err := secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
+	data, err := secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID1,
+			Property: k1,
+		},
+	})
 	tassert.Equal(t, v1, string(data))
 	tassert.Nil(t, err)
-	data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
+	data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID2,
+			Property: k2,
+		},
+	})
 	tassert.Nil(t, data)
 	tassert.EqualError(t, err, errSecretPayloadPermissionDenied)
 
-	data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
+	data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID1,
+			Property: k1,
+		},
+	})
 	tassert.Nil(t, data)
 	tassert.EqualError(t, err, errSecretPayloadPermissionDenied)
-	data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
+	data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID2,
+			Property: k2,
+		},
+	})
 	tassert.Equal(t, v2, string(data))
 	tassert.Nil(t, err)
 }
@@ -400,17 +462,37 @@ func TestGetSecretWithTwoApiEndpoints(t *testing.T) {
 
 	var data []byte
 
-	data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
+	data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID1,
+			Property: k1,
+		},
+	})
 	tassert.Equal(t, v1, string(data))
 	tassert.Nil(t, err)
-	data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
+	data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID2,
+			Property: k2,
+		},
+	})
 	tassert.Nil(t, data)
 	tassert.EqualError(t, err, errSecretPayloadNotFound)
 
-	data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
+	data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID1,
+			Property: k1,
+		},
+	})
 	tassert.Nil(t, data)
 	tassert.EqualError(t, err, errSecretPayloadNotFound)
-	data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
+	data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID1,
+			Property: k2,
+		},
+	})
 	tassert.Equal(t, v2, string(data))
 	tassert.Nil(t, err)
 }
@@ -442,19 +524,34 @@ func TestGetSecretWithIamTokenExpiration(t *testing.T) {
 
 	oldSecretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
 	tassert.Nil(t, err)
-	data, err = oldSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
+	data, err = oldSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID,
+			Property: k1,
+		},
+	})
 	tassert.Equal(t, v1, string(data))
 	tassert.Nil(t, err)
 
 	lockboxBackend.AdvanceClock(2 * tokenExpirationTime)
 
-	data, err = oldSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
+	data, err = oldSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID,
+			Property: k1,
+		},
+	})
 	tassert.Nil(t, data)
 	tassert.EqualError(t, err, "unable to request secret payload to get secret: iam token expired")
 
 	newSecretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
 	tassert.Nil(t, err)
-	data, err = newSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
+	data, err = newSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:      secretID,
+			Property: k1,
+		},
+	})
 	tassert.Equal(t, v1, string(data))
 	tassert.Nil(t, err)
 }
@@ -499,7 +596,11 @@ func TestGetSecretWithIamTokenCleanup(t *testing.T) {
 	// Access secretID1 with authorizedKey1, IAM token for authorizedKey1 should be cached
 	secretsClient, err := provider.NewClient(ctx, store1, k8sClient, namespace)
 	tassert.Nil(t, err)
-	_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1})
+	_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key: secretID1,
+		},
+	})
 	tassert.Nil(t, err)
 
 	tassert.True(t, provider.isIamTokenCached(authorizedKey1))
@@ -510,7 +611,11 @@ func TestGetSecretWithIamTokenCleanup(t *testing.T) {
 	// Access secretID2 with authorizedKey2, IAM token for authorizedKey2 should be cached
 	secretsClient, err = provider.NewClient(ctx, store2, k8sClient, namespace)
 	tassert.Nil(t, err)
-	_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2})
+	_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key: secretID2,
+		},
+	})
 	tassert.Nil(t, err)
 
 	tassert.True(t, provider.isIamTokenCached(authorizedKey1))
@@ -562,7 +667,11 @@ func TestGetSecretMap(t *testing.T) {
 	})
 	secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
 	tassert.Nil(t, err)
-	data, err := secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID})
+	data, err := secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key: secretID,
+		},
+	})
 	tassert.Nil(t, err)
 
 	tassert.Equal(
@@ -598,7 +707,12 @@ func TestGetSecretMapByVersionID(t *testing.T) {
 	})
 	secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
 	tassert.Nil(t, err)
-	data, err := secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
+	data, err := secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     secretID,
+			Version: oldVersionID,
+		},
+	})
 	tassert.Nil(t, err)
 
 	tassert.Equal(t, map[string][]byte{oldKey: []byte(oldVal)}, data)
@@ -608,11 +722,21 @@ func TestGetSecretMapByVersionID(t *testing.T) {
 		textEntry(newKey, newVal),
 	)
 
-	data, err = secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
+	data, err = secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     secretID,
+			Version: oldVersionID,
+		},
+	})
 	tassert.Nil(t, err)
 	tassert.Equal(t, map[string][]byte{oldKey: []byte(oldVal)}, data)
 
-	data, err = secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: newVersionID})
+	data, err = secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
+		Extract: esv1alpha1.ExternalSecretExtract{
+			Key:     secretID,
+			Version: newVersionID,
+		},
+	})
 	tassert.Nil(t, err)
 	tassert.Equal(t, map[string][]byte{newKey: []byte(newVal)}, data)
 }