Просмотр исходного кода

Merge pull request #784 from external-secrets/feature/hashivault-getallsecrets

Implements Hashicorp Vault GetAllSecrets
paul-the-alien[bot] 4 лет назад
Родитель
Сommit
fb056cc9b5
92 измененных файлов с 1018 добавлено и 295 удалено
  1. 11 0
      apis/externalsecrets/v1alpha1/externalsecret_types.go
  2. 19 2
      apis/externalsecrets/v1beta1/externalsecret_types.go
  3. 5 0
      apis/externalsecrets/v1beta1/zz_generated.deepcopy.go
  4. 23 2
      config/crds/bases/external-secrets.io_externalsecrets.yaml
  5. 23 2
      deploy/crds/bundle.yaml
  6. 1 1
      docs/guides-templating.md
  7. 1 1
      docs/provider-aws-parameter-store.md
  8. 86 7
      docs/provider-hashicorp-vault.md
  9. 3 3
      docs/provider-webhook.md
  10. 2 2
      docs/provider-yandex-lockbox.md
  11. 3 2
      docs/snippets/akeyless-external-secret-json.yaml
  12. 1 1
      docs/snippets/akeyless-external-secret.yaml
  13. 1 1
      docs/snippets/akeyless-secret-store.yaml
  14. 3 2
      docs/snippets/aws-anchore-engine-access-credentials-external-secret.yaml
  15. 1 1
      docs/snippets/aws-jenkins-credential-github-ssh-external-secret.yaml
  16. 1 1
      docs/snippets/aws-jenkins-credential-sonarqube-api-token-external-secret.yaml
  17. 1 1
      docs/snippets/aws-jenkins-credentials-harbor-chart-robot-external-secret.yaml
  18. 1 1
      docs/snippets/aws-parameter-store.yaml
  19. 1 1
      docs/snippets/aws-sm-external-secret.yaml
  20. 1 1
      docs/snippets/aws-sm-store.yaml
  21. 1 1
      docs/snippets/azkv-external-secret.yaml
  22. 1 1
      docs/snippets/azkv-secret-store-mi.yaml
  23. 1 1
      docs/snippets/azkv-secret-store.yaml
  24. 3 2
      docs/snippets/basic-external-secret.yaml
  25. 1 1
      docs/snippets/basic-secret-store.yaml
  26. 1 1
      docs/snippets/controller-class-store.yaml
  27. 3 2
      docs/snippets/fake-provider-es.yaml
  28. 1 1
      docs/snippets/fake-provider-store.yaml
  29. 1 1
      docs/snippets/full-cluster-secret-store.yaml
  30. 13 4
      docs/snippets/full-external-secret.yaml
  31. 1 1
      docs/snippets/full-secret-store.yaml
  32. 3 2
      docs/snippets/gcpsm-data-from-external-secret.yaml
  33. 1 1
      docs/snippets/gcpsm-docker-config-externalsecret.yaml
  34. 1 1
      docs/snippets/gcpsm-external-secret.yaml
  35. 1 1
      docs/snippets/gcpsm-pod-wi-secret-store.yaml
  36. 1 1
      docs/snippets/gcpsm-secret-store.yaml
  37. 1 1
      docs/snippets/gcpsm-ssh-auth-externalsecret.yaml
  38. 1 1
      docs/snippets/gcpsm-tls-externalsecret.yaml
  39. 1 1
      docs/snippets/gcpsm-wi-secret-store.yaml
  40. 3 2
      docs/snippets/gitlab-external-secret-json.yaml
  41. 1 1
      docs/snippets/gitlab-external-secret.yaml
  42. 1 1
      docs/snippets/gitlab-secret-store.yaml
  43. 1 1
      docs/snippets/gitops/crs/clusterSecretStore.yaml
  44. 1 1
      docs/snippets/ibm-es-types.yaml
  45. 1 1
      docs/snippets/ibm-external-secret.yaml
  46. 1 1
      docs/snippets/ibm-secret-store.yaml
  47. 1 1
      docs/snippets/jwk-template-v2-external-secret.yaml
  48. 1 1
      docs/snippets/multiline-template-v1-external-secret.yaml
  49. 1 1
      docs/snippets/multiline-template-v2-external-secret.yaml
  50. 3 2
      docs/snippets/oracle-external-secret.yaml
  51. 2 2
      docs/snippets/oracle-secret-store.yaml
  52. 1 1
      docs/snippets/pkcs12-template-v1-external-secret.yaml
  53. 1 1
      docs/snippets/pkcs12-template-v2-external-secret.yaml
  54. 3 3
      docs/snippets/provider-aws-access.md
  55. 1 1
      docs/snippets/template-v1-from-secret.yaml
  56. 1 1
      docs/snippets/template-v2-from-secret.yaml
  57. 1 1
      docs/snippets/vault-anchore-engine-access-credentials-external-secret.yaml
  58. 1 1
      docs/snippets/vault-approle-store.yaml
  59. 1 1
      docs/snippets/vault-jenkins-credential-github-ssh-access-external-secret.yaml
  60. 1 1
      docs/snippets/vault-jenkins-credential-harbor-chart-robot-external-secret.yaml
  61. 1 1
      docs/snippets/vault-jenkins-credential-sonarqube-api-token-external-secret.yaml
  62. 1 1
      docs/snippets/vault-jwt-store.yaml
  63. 1 1
      docs/snippets/vault-kubernetes-store.yaml
  64. 1 1
      docs/snippets/vault-ldap-store.yaml
  65. 1 1
      docs/snippets/vault-token-store.yaml
  66. 45 0
      docs/spec.md
  67. 2 2
      e2e/framework/eso.go
  68. 2 2
      e2e/framework/framework.go
  69. 6 6
      e2e/framework/testcase.go
  70. 7 7
      e2e/suite/akeyless/provider.go
  71. 7 7
      e2e/suite/alibaba/provider.go
  72. 10 10
      e2e/suite/aws/common.go
  73. 15 15
      e2e/suite/aws/parameterstore/provider.go
  74. 15 15
      e2e/suite/aws/secretsmanager/provider.go
  75. 3 3
      e2e/suite/azure/azure_cert.go
  76. 3 3
      e2e/suite/azure/azure_key.go
  77. 6 6
      e2e/suite/azure/provider.go
  78. 69 33
      e2e/suite/common/common.go
  79. 6 5
      e2e/suite/gcp/gcp.go
  80. 2 2
      e2e/suite/gcp/gcp_managed.go
  81. 14 14
      e2e/suite/gcp/provider.go
  82. 7 7
      e2e/suite/gitlab/provider.go
  83. 7 7
      e2e/suite/oracle/provider.go
  84. 6 6
      e2e/suite/template/provider.go
  85. 13 11
      e2e/suite/template/template.go
  86. 18 18
      e2e/suite/vault/provider.go
  87. 15 6
      e2e/suite/vault/vault.go
  88. 11 1
      pkg/controllers/externalsecret/externalsecret_controller.go
  89. 34 0
      pkg/provider/vault/fake/vault.go
  90. 172 21
      pkg/provider/vault/vault.go
  91. 230 0
      pkg/provider/vault/vault_test.go
  92. 35 0
      pkg/utils/utils.go

+ 11 - 0
apis/externalsecrets/v1alpha1/externalsecret_types.go

@@ -141,8 +141,19 @@ type ExternalSecretDataRemoteRef struct {
 	// +optional
 	// Used to select a specific property of the Provider value (if a map), if supported
 	Property string `json:"property,omitempty"`
+	// +optional
+	// Used to define a conversion Strategy
+	// +kubebuilder:default="Default"
+	ConversionStrategy ExternalSecretConversionStrategy `json:"conversionStrategy,omitempty"`
 }
 
+type ExternalSecretConversionStrategy string
+
+const (
+	ExternalSecretConversionDefault ExternalSecretConversionStrategy = "Default"
+	ExternalSecretConversionUnicode ExternalSecretConversionStrategy = "Unicode"
+)
+
 // ExternalSecretSpec defines the desired state of ExternalSecret.
 type ExternalSecretSpec struct {
 	SecretStoreRef SecretStoreRef `json:"secretStoreRef"`

+ 19 - 2
apis/externalsecrets/v1beta1/externalsecret_types.go

@@ -159,8 +159,20 @@ type ExternalSecretDataRemoteRef struct {
 	// +optional
 	// Used to select a specific property of the Provider value (if a map), if supported
 	Property string `json:"property,omitempty"`
+
+	// +optional
+	// Used to define a conversion Strategy
+	// +kubebuilder:default="Default"
+	ConversionStrategy ExternalSecretConversionStrategy `json:"conversionStrategy,omitempty"`
 }
 
+type ExternalSecretConversionStrategy string
+
+const (
+	ExternalSecretConversionDefault ExternalSecretConversionStrategy = "Default"
+	ExternalSecretConversionUnicode ExternalSecretConversionStrategy = "Unicode"
+)
+
 // +kubebuilder:validation:MinProperties=1
 // +kubebuilder:validation:MaxProperties=1
 type ExternalSecretDataFromRemoteRef struct {
@@ -172,9 +184,10 @@ type ExternalSecretDataFromRemoteRef struct {
 	Find *ExternalSecretFind `json:"find,omitempty"`
 }
 
-// +kubebuilder:validation:MinProperties=1
-// +kubebuilder:validation:MaxProperties=1
 type ExternalSecretFind struct {
+	// A root path to start the find operations.
+	// +optional
+	Path *string `json:"path,omitempty"`
 	// Finds secrets based on the name.
 	// +optional
 	Name *FindName `json:"name,omitempty"`
@@ -182,6 +195,10 @@ type ExternalSecretFind struct {
 	// Find secrets based on tags.
 	// +optional
 	Tags map[string]string `json:"tags,omitempty"`
+	// +optional
+	// Used to define a conversion Strategy
+	// +kubebuilder:default="Default"
+	ConversionStrategy ExternalSecretConversionStrategy `json:"conversionStrategy,omitempty"`
 }
 
 type FindName struct {

+ 5 - 0
apis/externalsecrets/v1beta1/zz_generated.deepcopy.go

@@ -462,6 +462,11 @@ func (in *ExternalSecretDataRemoteRef) DeepCopy() *ExternalSecretDataRemoteRef {
 // 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
+	if in.Path != nil {
+		in, out := &in.Path, &out.Path
+		*out = new(string)
+		**out = **in
+	}
 	if in.Name != nil {
 		in, out := &in.Name, &out.Name
 		*out = new(FindName)

+ 23 - 2
config/crds/bases/external-secrets.io_externalsecrets.yaml

@@ -59,6 +59,10 @@ spec:
                       description: ExternalSecretDataRemoteRef defines Provider data
                         location.
                       properties:
+                        conversionStrategy:
+                          default: Default
+                          description: Used to define a conversion Strategy
+                          type: string
                         key:
                           description: Key is the key used in the Provider, mandatory
                           type: string
@@ -87,6 +91,10 @@ spec:
                 items:
                   description: ExternalSecretDataRemoteRef defines Provider data location.
                   properties:
+                    conversionStrategy:
+                      default: Default
+                      description: Used to define a conversion Strategy
+                      type: string
                     key:
                       description: Key is the key used in the Provider, mandatory
                       type: string
@@ -294,6 +302,10 @@ spec:
                       description: ExternalSecretDataRemoteRef defines Provider data
                         location.
                       properties:
+                        conversionStrategy:
+                          default: Default
+                          description: Used to define a conversion Strategy
+                          type: string
                         key:
                           description: Key is the key used in the Provider, mandatory
                           type: string
@@ -327,6 +339,10 @@ spec:
                       description: Used to extract multiple key/value pairs from one
                         secret
                       properties:
+                        conversionStrategy:
+                          default: Default
+                          description: Used to define a conversion Strategy
+                          type: string
                         key:
                           description: Key is the key used in the Provider, mandatory
                           type: string
@@ -343,9 +359,11 @@ spec:
                       type: object
                     find:
                       description: Used to find secrets based on tags or regular expressions
-                      maxProperties: 1
-                      minProperties: 1
                       properties:
+                        conversionStrategy:
+                          default: Default
+                          description: Used to define a conversion Strategy
+                          type: string
                         name:
                           description: Finds secrets based on the name.
                           properties:
@@ -353,6 +371,9 @@ spec:
                               description: Finds secrets base
                               type: string
                           type: object
+                        path:
+                          description: A root path to start the find operations.
+                          type: string
                         tags:
                           additionalProperties:
                             type: string

+ 23 - 2
deploy/crds/bundle.yaml

@@ -2019,6 +2019,10 @@ spec:
                       remoteRef:
                         description: ExternalSecretDataRemoteRef defines Provider data location.
                         properties:
+                          conversionStrategy:
+                            default: Default
+                            description: Used to define a conversion Strategy
+                            type: string
                           key:
                             description: Key is the key used in the Provider, mandatory
                             type: string
@@ -2043,6 +2047,10 @@ spec:
                   items:
                     description: ExternalSecretDataRemoteRef defines Provider data location.
                     properties:
+                      conversionStrategy:
+                        default: Default
+                        description: Used to define a conversion Strategy
+                        type: string
                       key:
                         description: Key is the key used in the Provider, mandatory
                         type: string
@@ -2226,6 +2234,10 @@ spec:
                       remoteRef:
                         description: ExternalSecretDataRemoteRef defines Provider data location.
                         properties:
+                          conversionStrategy:
+                            default: Default
+                            description: Used to define a conversion Strategy
+                            type: string
                           key:
                             description: Key is the key used in the Provider, mandatory
                             type: string
@@ -2254,6 +2266,10 @@ spec:
                       extract:
                         description: Used to extract multiple key/value pairs from one secret
                         properties:
+                          conversionStrategy:
+                            default: Default
+                            description: Used to define a conversion Strategy
+                            type: string
                           key:
                             description: Key is the key used in the Provider, mandatory
                             type: string
@@ -2268,9 +2284,11 @@ spec:
                         type: object
                       find:
                         description: Used to find secrets based on tags or regular expressions
-                        maxProperties: 1
-                        minProperties: 1
                         properties:
+                          conversionStrategy:
+                            default: Default
+                            description: Used to define a conversion Strategy
+                            type: string
                           name:
                             description: Finds secrets based on the name.
                             properties:
@@ -2278,6 +2296,9 @@ spec:
                                 description: Finds secrets base
                                 type: string
                             type: object
+                          path:
+                            description: A root path to start the find operations.
+                            type: string
                           tags:
                             additionalProperties:
                               type: string

+ 1 - 1
docs/guides-templating.md

@@ -96,7 +96,7 @@ In addition to that you can use over 200+ [sprig functions](http://masterminds.g
 
 ## Migrating from v1
 
-You have to opt-in to use the new engine version by specifying `template.engineVersion=v2`:
+If you are still using `v1alpha1`, You have to opt-in to use the new engine version by specifying `template.engineVersion=v2`:
 
 ```yaml
 apiVersion: external-secrets.io/v1alpha1

+ 1 - 1
docs/provider-aws-parameter-store.md

@@ -54,7 +54,7 @@ Consider the following JSON object that is stored in the Parameter Store key `my
 
 This is an example on how you would look up nested keys in the above json object:
 ``` yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: example

+ 86 - 7
docs/provider-hashicorp-vault.md

@@ -11,7 +11,7 @@ management. Vault itself implements lots of different secret engines, as of now
 First, create a SecretStore with a vault backend. For the sake of simplicity we'll use a static token `root`:
 
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: vault-backend
@@ -46,7 +46,7 @@ vault kv put secret/foo my-value=s3cr3t
 Now create a ExternalSecret that uses the above SecretStore:
 
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: vault-example
@@ -76,7 +76,7 @@ data:
 You can fetch all key/value pairs for a given path If you leave the `remoteRef.property` empty. This returns the json-encoded secret value for that path.
 
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: vault-example
@@ -105,7 +105,7 @@ Given the following secret - assume its path is `/dev/config`:
 
 You can set the `remoteRef.property` to point to the nested key using a [gjson](https://github.com/tidwall/gjson) expression.
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: vault-example
@@ -141,15 +141,16 @@ Given the following secret - assume its path is `/dev/config`:
 
 You can set the `remoteRef.property` to point to the nested key using a [gjson](https://github.com/tidwall/gjson) expression.
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: vault-example
 spec:
   # ...
   dataFrom:
-  - key: /dev/config
-    property: foo.nested
+  - extract:
+      key: /dev/config
+      property: foo.nested
 ```
 
 That results in a secret with these values:
@@ -158,6 +159,84 @@ bar=mysecret
 baz=bang
 ```
 
+#### Getting multiple secrets
+
+You can extract multiple secrets from Hashicorp vault by using `dataFrom.Find`
+
+Currently, `dataFrom.Find` allows users to fetch secret names that match a given regexp pattern, or fetch secrets whose `custom_metadata` tags match a predefined set.
+
+
+!!! warning
+    The way hashicorp Vault currently allows LIST operations is through the existence of a secret metadata. If you delete the secret, you will also need to delete the secret's metadata or this will currently make Find operations fail.
+
+Given the following secret - assume its path is `/dev/config`:
+```json
+{
+  "foo": {
+    "nested": {
+      "bar": "mysecret",
+      "baz": "bang"
+    }
+  }
+}
+```
+
+Also consider the following secret has the following `custom_metadata`:
+```json
+{
+  "environment": "dev",
+  "component": "app-1"
+}
+```
+
+It is possible to find this secret by all the following possibilities:
+```yaml
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+  name: vault-example
+spec:
+  # ...
+  dataFrom: 
+  - find: #will return every secret with 'dev' in it (including paths) 
+      name: 
+        regexp: dev
+  - find: #will return every secret matching environment:dev tags from dev/ folder and beyond 
+      tags: 
+        environment: dev
+```
+will generate a secret with: 
+```json
+{
+  "dev_config":"{\"foo\":{\"nested\":{\"bar\":\"mysecret\",\"baz\":\"bang\"}}}"
+}
+```
+
+Currently, `Find` operations are recursive throughout a given vault folder, starting on `provider.Path` definition. It is recommended to narrow down the scope of search by setting a `find.path` variable. This is also useful to automatically reduce the resulting secret key names:
+```yaml
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+  name: vault-example
+spec:
+  # ...
+  dataFrom: 
+  - find: #will return every secret from dev/ folder 
+      path: dev
+      name: 
+        regexp: ".*"
+  - find: #will return every secret matching environment:dev tags from dev/ folder
+      path: dev
+      tags: 
+        environment: dev
+```
+Will generate a secret with:
+```json
+{
+  "config":"{\"foo\": {\"nested\": {\"bar\": \"mysecret\",\"baz\": \"bang\"}}}"
+}
+
+```
 ### Authentication
 
 We support five different modes for authentication:

+ 3 - 3
docs/provider-webhook.md

@@ -8,7 +8,7 @@ First, create a SecretStore with a webhook backend.  We'll use a static user/pas
 
 ```yaml
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: webhook-backend
@@ -43,7 +43,7 @@ NB: This is obviously not practical because it just returns the key as the resul
 Now create an ExternalSecret that uses the above SecretStore:
 
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: webhook-example
@@ -83,7 +83,7 @@ Each secret has a `name` property which determines the name of the object in the
 ### All Parameters
 
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ClusterSecretStore
 metadata:
   name: statervault

+ 2 - 2
docs/provider-yandex-lockbox.md

@@ -26,7 +26,7 @@ kubectl create secret generic yc-auth --from-file=authorized-key=authorized-key.
 ```
 * Create a [SecretStore](../api-secretstore/) pointing to `yc-auth` k8s secret:
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: secret-store
@@ -63,7 +63,7 @@ yc lockbox secret list-access-bindings --name lockbox-secret
 ```
 * Create an [ExternalSecret](../api-externalsecret/) pointing to `secret-store` and `lockbox-secret`:
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: external-secret

+ 3 - 2
docs/snippets/akeyless-external-secret-json.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: akeyless-external-secret-example-json
@@ -15,4 +15,5 @@ spec:
 
   # for json formatted secrets: each key in the json will be used as the secret key in the SECRET k8s target object
   dataFrom:
-  - key: secret-name # Full path of the secret on Akeyless
+  - extract:
+      key: secret-name # Full path of the secret on Akeyless

+ 1 - 1
docs/snippets/akeyless-external-secret.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: akeyless-external-secret-example

+ 1 - 1
docs/snippets/akeyless-secret-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: akeyless-secret-store

+ 3 - 2
docs/snippets/aws-anchore-engine-access-credentials-external-secret.yaml

@@ -1,5 +1,5 @@
 ---
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: anchore-access-credentials
@@ -12,4 +12,5 @@ spec:
   target:
     name: anchore-access-credentials
   dataFrom:
-  - key: service/anchore-engine/engineAccess
+  - extract:
+      key: service/anchore-engine/engineAccess

+ 1 - 1
docs/snippets/aws-jenkins-credential-github-ssh-external-secret.yaml

@@ -1,5 +1,5 @@
 ---
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: github-ssh-access

+ 1 - 1
docs/snippets/aws-jenkins-credential-sonarqube-api-token-external-secret.yaml

@@ -1,5 +1,5 @@
 ---
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: sonarqube-api-token

+ 1 - 1
docs/snippets/aws-jenkins-credentials-harbor-chart-robot-external-secret.yaml

@@ -1,5 +1,5 @@
 ---
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: harbor-chart-robot

+ 1 - 1
docs/snippets/aws-parameter-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: secretstore-sample

+ 1 - 1
docs/snippets/aws-sm-external-secret.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: example

+ 1 - 1
docs/snippets/aws-sm-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: secretstore-sample

+ 1 - 1
docs/snippets/azkv-external-secret.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: example-external-secret

+ 1 - 1
docs/snippets/azkv-secret-store-mi.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: example-secret-store

+ 1 - 1
docs/snippets/azkv-secret-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: example-secret-store

+ 3 - 2
docs/snippets/basic-external-secret.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: example
@@ -17,4 +17,5 @@ spec:
       version: provider-key-version
       property: provider-key-property
   dataFrom:
-  - key: remote-key-in-the-provider
+  - extract:
+      key: remote-key-in-the-provider

+ 1 - 1
docs/snippets/basic-secret-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: secretstore-sample

+ 1 - 1
docs/snippets/controller-class-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: controller-custom-example

+ 3 - 2
docs/snippets/fake-provider-es.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: example
@@ -15,4 +15,5 @@ spec:
       key: /foo/bar
       version: v1
   dataFrom:
-  - key: /foo/baz
+  - extract:
+      key: /foo/baz

+ 1 - 1
docs/snippets/fake-provider-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ClusterSecretStore
 metadata:
   name: fake

+ 1 - 1
docs/snippets/full-cluster-secret-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ClusterSecretStore
 metadata:
   name: example

+ 13 - 4
docs/snippets/full-external-secret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: "hello-world"
@@ -73,9 +73,18 @@ spec:
   # Used to fetch all properties from the Provider key
   # If multiple dataFrom are specified, secrets are merged in the specified order
   dataFrom:
-  - key: provider-key
-    version: provider-key-version
-    property: provider-key-property
+  - extract:
+      key: provider-key
+      version: provider-key-version
+      property: provider-key-property
+      conversionStrategy: Default
+  - find:
+      path: path-to-filter 
+      name: 
+        regexp: ".*foobar.*"
+      tags: 
+        foo: bar
+      conversionStrategy: Unicode
 
 status:
   # refreshTime is the time and date the external secret was fetched and

+ 1 - 1
docs/snippets/full-secret-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: example

+ 3 - 2
docs/snippets/gcpsm-data-from-external-secret.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: example
@@ -11,4 +11,5 @@ spec:
     name: secret-to-be-created  # name of the k8s Secret to be created
     creationPolicy: Owner
   dataFrom:
-  - key: all-keys-example-secret  # name of the GCPSM secret
+  - extract:
+      key: all-keys-example-secret  # name of the GCPSM secret

+ 1 - 1
docs/snippets/gcpsm-docker-config-externalsecret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: dk-cfg-example

+ 1 - 1
docs/snippets/gcpsm-external-secret.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: example

+ 1 - 1
docs/snippets/gcpsm-pod-wi-secret-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: example

+ 1 - 1
docs/snippets/gcpsm-secret-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: example

+ 1 - 1
docs/snippets/gcpsm-ssh-auth-externalsecret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: ssh-auth-example

+ 1 - 1
docs/snippets/gcpsm-tls-externalsecret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: template-tls-example

+ 1 - 1
docs/snippets/gcpsm-wi-secret-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ClusterSecretStore
 metadata:
   name: example

+ 3 - 2
docs/snippets/gitlab-external-secret-json.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: gitlab-external-secret-example
@@ -15,4 +15,5 @@ spec:
 
   # each secret name in the KV will be used as the secret key in the SECRET k8s target object
   dataFrom:
-  - key: "myJsonVariable" # Key of the variable on Gitlab
+  - extract:
+      key: "myJsonVariable" # Key of the variable on Gitlab

+ 1 - 1
docs/snippets/gitlab-external-secret.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: gitlab-external-secret-example

+ 1 - 1
docs/snippets/gitlab-secret-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: gitlab-secret-store

+ 1 - 1
docs/snippets/gitops/crs/clusterSecretStore.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ClusterSecretStore
 metadata:
   name: vault-backend-global

+ 1 - 1
docs/snippets/ibm-es-types.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: ibm-sample

+ 1 - 1
docs/snippets/ibm-external-secret.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: external-secret-sample

+ 1 - 1
docs/snippets/ibm-secret-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: secretstore-sample

+ 1 - 1
docs/snippets/jwk-template-v2-external-secret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: template

+ 1 - 1
docs/snippets/multiline-template-v1-external-secret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: template

+ 1 - 1
docs/snippets/multiline-template-v2-external-secret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: template

+ 3 - 2
docs/snippets/oracle-external-secret.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: example
@@ -11,4 +11,5 @@ spec:
     name: secret-to-be-created # Name for the secret on the cluster
     creationPolicy: Owner
   dataFrom:
-    - key: the-secret-name
+  - extract:
+      key: the-secret-name

+ 2 - 2
docs/snippets/oracle-secret-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: example-instance-principal
@@ -10,7 +10,7 @@ spec:
 
 ---
 
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: example-auth

+ 1 - 1
docs/snippets/pkcs12-template-v1-external-secret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: template

+ 1 - 1
docs/snippets/pkcs12-template-v2-external-secret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: template

+ 3 - 3
docs/snippets/provider-aws-access.md

@@ -13,7 +13,7 @@ You can attach a role to the pod using [IRSA](https://docs.aws.amazon.com/eks/la
 Based on the Pod's identity you can do a `sts:assumeRole` before fetching the secrets to limit access to certain keys in your provider. This is optional.
 
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: team-b-store
@@ -33,7 +33,7 @@ spec:
 You can store Access Key ID & Secret Access Key in a `Kind=Secret` and reference it from a SecretStore.
 
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: team-b-store
@@ -78,7 +78,7 @@ metadata:
 Reference the service account from above in the Secret Store:
 
 ```yaml
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: secretstore-sample

+ 1 - 1
docs/snippets/template-v1-from-secret.yaml

@@ -14,7 +14,7 @@ data:
         password: "{{ .password | toString }}" # <-- convert []byte to string
         user: "{{ .user | toString }}"         # <-- convert []byte to string
 ---
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: my-template-example

+ 1 - 1
docs/snippets/template-v2-from-secret.yaml

@@ -14,7 +14,7 @@ data:
         password: "{{ .password }}"
         user: "{{ .user }}"
 ---
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: my-template-example

+ 1 - 1
docs/snippets/vault-anchore-engine-access-credentials-external-secret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: anchore-access-credentials

+ 1 - 1
docs/snippets/vault-approle-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: vault-backend

+ 1 - 1
docs/snippets/vault-jenkins-credential-github-ssh-access-external-secret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: github-ssh-access

+ 1 - 1
docs/snippets/vault-jenkins-credential-harbor-chart-robot-external-secret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: harbor-chart-robot

+ 1 - 1
docs/snippets/vault-jenkins-credential-sonarqube-api-token-external-secret.yaml

@@ -1,5 +1,5 @@
 {% raw %}
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: ExternalSecret
 metadata:
   name: sonarqube-api-token

+ 1 - 1
docs/snippets/vault-jwt-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: vault-backend

+ 1 - 1
docs/snippets/vault-kubernetes-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: vault-backend

+ 1 - 1
docs/snippets/vault-ldap-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: vault-backend

+ 1 - 1
docs/snippets/vault-token-store.yaml

@@ -1,4 +1,4 @@
-apiVersion: external-secrets.io/v1alpha1
+apiVersion: external-secrets.io/v1beta1
 kind: SecretStore
 metadata:
   name: vault-backend

+ 45 - 0
docs/spec.md

@@ -996,6 +996,27 @@ ExternalSecretStatus
 <td></td>
 </tr></tbody>
 </table>
+<h3 id="external-secrets.io/v1alpha1.ExternalSecretConversionStrategy">ExternalSecretConversionStrategy
+(<code>string</code> alias)</p></h3>
+<p>
+(<em>Appears on:</em>
+<a href="#external-secrets.io/v1alpha1.ExternalSecretDataRemoteRef">ExternalSecretDataRemoteRef</a>)
+</p>
+<p>
+</p>
+<table>
+<thead>
+<tr>
+<th>Value</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody><tr><td><p>&#34;Default&#34;</p></td>
+<td></td>
+</tr><tr><td><p>&#34;Unicode&#34;</p></td>
+<td></td>
+</tr></tbody>
+</table>
 <h3 id="external-secrets.io/v1alpha1.ExternalSecretCreationPolicy">ExternalSecretCreationPolicy
 (<code>string</code> alias)</p></h3>
 <p>
@@ -1117,6 +1138,20 @@ string
 <p>Used to select a specific property of the Provider value (if a map), if supported</p>
 </td>
 </tr>
+<tr>
+<td>
+<code>conversionStrategy</code></br>
+<em>
+<a href="#external-secrets.io/v1alpha1.ExternalSecretConversionStrategy">
+ExternalSecretConversionStrategy
+</a>
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>Used to define a conversion Strategy</p>
+</td>
+</tr>
 </tbody>
 </table>
 <h3 id="external-secrets.io/v1alpha1.ExternalSecretSpec">ExternalSecretSpec
@@ -1793,6 +1828,16 @@ string
 <td>
 </td>
 </tr>
+<tr>
+<td>
+<code>clusterProjectID</code></br>
+<em>
+string
+</em>
+</td>
+<td>
+</td>
+</tr>
 </tbody>
 </table>
 <h3 id="external-secrets.io/v1alpha1.GenericStore">GenericStore

+ 2 - 2
e2e/framework/eso.go

@@ -25,7 +25,7 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/wait"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 )
 
 // WaitForSecretValue waits until a secret comes into existence and compares the secret.Data
@@ -56,7 +56,7 @@ func equalSecrets(exp, ts *v1.Secret) bool {
 	}
 
 	// secret contains data hash property which must be ignored
-	delete(ts.ObjectMeta.Annotations, esv1alpha1.AnnotationDataHash)
+	delete(ts.ObjectMeta.Annotations, esv1beta1.AnnotationDataHash)
 	if len(ts.ObjectMeta.Annotations) == 0 {
 		ts.ObjectMeta.Annotations = nil
 	}

+ 2 - 2
e2e/framework/framework.go

@@ -26,7 +26,7 @@ import (
 	"k8s.io/client-go/rest"
 	crclient "sigs.k8s.io/controller-runtime/pkg/client"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework/addon"
 	"github.com/external-secrets/external-secrets/e2e/framework/log"
 	"github.com/external-secrets/external-secrets/e2e/framework/util"
@@ -34,7 +34,7 @@ import (
 
 func init() {
 	_ = kscheme.AddToScheme(util.Scheme)
-	_ = esv1alpha1.AddToScheme(util.Scheme)
+	_ = esv1beta1.AddToScheme(util.Scheme)
 }
 
 type Framework struct {

+ 6 - 6
e2e/framework/testcase.go

@@ -21,7 +21,7 @@ import (
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework/log"
 )
 
@@ -30,7 +30,7 @@ var TargetSecretName = "target-secret"
 // TestCase contains the test infra to run a table driven test.
 type TestCase struct {
 	Framework      *Framework
-	ExternalSecret *esv1alpha1.ExternalSecret
+	ExternalSecret *esv1beta1.ExternalSecret
 	Secrets        map[string]string
 	ExpectedSecret *v1.Secret
 }
@@ -85,16 +85,16 @@ func TableFunc(f *Framework, prov SecretStoreProvider) func(...func(*TestCase))
 func makeDefaultTestCase(f *Framework) *TestCase {
 	return &TestCase{
 		Framework: f,
-		ExternalSecret: &esv1alpha1.ExternalSecret{
+		ExternalSecret: &esv1beta1.ExternalSecret{
 			ObjectMeta: metav1.ObjectMeta{
 				Name:      "e2e-es",
 				Namespace: f.Namespace.Name,
 			},
-			Spec: esv1alpha1.ExternalSecretSpec{
-				SecretStoreRef: esv1alpha1.SecretStoreRef{
+			Spec: esv1beta1.ExternalSecretSpec{
+				SecretStoreRef: esv1beta1.SecretStoreRef{
 					Name: f.Namespace.Name,
 				},
-				Target: esv1alpha1.ExternalSecretTarget{
+				Target: esv1beta1.ExternalSecretTarget{
 					Name: TargetSecretName,
 				},
 			},

+ 7 - 7
e2e/suite/akeyless/provider.go

@@ -36,7 +36,7 @@ import (
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
@@ -129,16 +129,16 @@ func (a *akeylessProvider) BeforeEach() {
 	Expect(err).ToNot(HaveOccurred())
 
 	// Creating Akeyless secret store
-	secretStore := &esv1alpha1.SecretStore{
+	secretStore := &esv1beta1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      a.framework.Namespace.Name,
 			Namespace: a.framework.Namespace.Name,
 		},
-		Spec: esv1alpha1.SecretStoreSpec{
-			Provider: &esv1alpha1.SecretStoreProvider{
-				Akeyless: &esv1alpha1.AkeylessProvider{
-					Auth: &esv1alpha1.AkeylessAuth{
-						SecretRef: esv1alpha1.AkeylessAuthSecretRef{
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				Akeyless: &esv1beta1.AkeylessProvider{
+					Auth: &esv1beta1.AkeylessAuth{
+						SecretRef: esv1beta1.AkeylessAuthSecretRef{
 							AccessID: esmeta.SecretKeySelector{
 								Name: "access-id-secret",
 								Key:  "access-id",

+ 7 - 7
e2e/suite/alibaba/provider.go

@@ -28,7 +28,7 @@ import (
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
@@ -97,16 +97,16 @@ func (s *alibabaProvider) BeforeEach() {
 	Expect(err).ToNot(HaveOccurred())
 
 	// Creating Alibaba secret store
-	secretStore := &esv1alpha1.SecretStore{
+	secretStore := &esv1beta1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      s.framework.Namespace.Name,
 			Namespace: s.framework.Namespace.Name,
 		},
-		Spec: esv1alpha1.SecretStoreSpec{
-			Provider: &esv1alpha1.SecretStoreProvider{
-				Alibaba: &esv1alpha1.AlibabaProvider{
-					Auth: &esv1alpha1.AlibabaAuth{
-						SecretRef: esv1alpha1.AlibabaAuthSecretRef{
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				Alibaba: &esv1beta1.AlibabaProvider{
+					Auth: &esv1beta1.AlibabaAuth{
+						SecretRef: esv1beta1.AlibabaAuthSecretRef{
 							AccessKeyID: esmeta.SecretKeySelector{
 								Name: "kms-secret",
 								Key:  "keyid",

+ 10 - 10
e2e/suite/aws/common.go

@@ -21,7 +21,7 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmetav1 "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
@@ -41,18 +41,18 @@ func MountedIRSAStoreName(f *framework.Framework) string {
 }
 
 func UseClusterSecretStore(tc *framework.TestCase) {
-	tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.ClusterSecretStoreKind
+	tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1beta1.ClusterSecretStoreKind
 	tc.ExternalSecret.Spec.SecretStoreRef.Name = ReferencedIRSAStoreName(tc.Framework)
 }
 
 func UseMountedIRSAStore(tc *framework.TestCase) {
-	tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.SecretStoreKind
+	tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1beta1.SecretStoreKind
 	tc.ExternalSecret.Spec.SecretStoreRef.Name = MountedIRSAStoreName(tc.Framework)
 }
 
 // StaticStore is namespaced and references
 // static credentials from a secret.
-func SetupStaticStore(f *framework.Framework, kid, sak, region string, serviceType esv1alpha1.AWSServiceType) {
+func SetupStaticStore(f *framework.Framework, kid, sak, region string, serviceType esv1beta1.AWSServiceType) {
 	awsCreds := &corev1.Secret{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      StaticCredentialsSecretName,
@@ -66,18 +66,18 @@ func SetupStaticStore(f *framework.Framework, kid, sak, region string, serviceTy
 	err := f.CRClient.Create(context.Background(), awsCreds)
 	Expect(err).ToNot(HaveOccurred())
 
-	secretStore := &esv1alpha1.SecretStore{
+	secretStore := &esv1beta1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      f.Namespace.Name,
 			Namespace: f.Namespace.Name,
 		},
-		Spec: esv1alpha1.SecretStoreSpec{
-			Provider: &esv1alpha1.SecretStoreProvider{
-				AWS: &esv1alpha1.AWSProvider{
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				AWS: &esv1beta1.AWSProvider{
 					Service: serviceType,
 					Region:  region,
-					Auth: esv1alpha1.AWSAuth{
-						SecretRef: &esv1alpha1.AWSAuthSecretRef{
+					Auth: esv1beta1.AWSAuth{
+						SecretRef: &esv1beta1.AWSAuthSecretRef{
 							AccessKeyID: esmetav1.SecretKeySelector{
 								Name: StaticCredentialsSecretName,
 								Key:  "kid",

+ 15 - 15
e2e/suite/aws/parameterstore/provider.go

@@ -31,7 +31,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmetav1 "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	"github.com/external-secrets/external-secrets/e2e/framework/log"
@@ -67,14 +67,14 @@ func NewProvider(f *framework.Framework, kid, sak, region, saName, saNamespace s
 	}
 
 	BeforeEach(func() {
-		common.SetupStaticStore(f, kid, sak, region, esv1alpha1.AWSServiceParameterStore)
+		common.SetupStaticStore(f, kid, sak, region, esv1beta1.AWSServiceParameterStore)
 		prov.SetupReferencedIRSAStore()
 		prov.SetupMountedIRSAStore()
 	})
 
 	AfterEach(func() {
 		// Cleanup ClusterSecretStore
-		err := prov.framework.CRClient.Delete(context.Background(), &esv1alpha1.ClusterSecretStore{
+		err := prov.framework.CRClient.Delete(context.Background(), &esv1beta1.ClusterSecretStore{
 			ObjectMeta: metav1.ObjectMeta{
 				Name: common.ReferencedIRSAStoreName(f),
 			},
@@ -116,17 +116,17 @@ func (s *Provider) DeleteSecret(key string) {
 // MountedIRSAStore is a SecretStore without auth config
 // ESO relies on the pod-mounted ServiceAccount when using this store.
 func (s *Provider) SetupMountedIRSAStore() {
-	secretStore := &esv1alpha1.SecretStore{
+	secretStore := &esv1beta1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      common.MountedIRSAStoreName(s.framework),
 			Namespace: s.framework.Namespace.Name,
 		},
-		Spec: esv1alpha1.SecretStoreSpec{
-			Provider: &esv1alpha1.SecretStoreProvider{
-				AWS: &esv1alpha1.AWSProvider{
-					Service: esv1alpha1.AWSServiceParameterStore,
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				AWS: &esv1beta1.AWSProvider{
+					Service: esv1beta1.AWSServiceParameterStore,
 					Region:  s.region,
-					Auth:    esv1alpha1.AWSAuth{},
+					Auth:    esv1beta1.AWSAuth{},
 				},
 			},
 		},
@@ -139,18 +139,18 @@ func (s *Provider) SetupMountedIRSAStore() {
 // that references a (IRSA-) ServiceAccount in the default namespace.
 func (s *Provider) SetupReferencedIRSAStore() {
 	log.Logf("creating IRSA ClusterSecretStore %s", s.framework.Namespace.Name)
-	secretStore := &esv1alpha1.ClusterSecretStore{
+	secretStore := &esv1beta1.ClusterSecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: common.ReferencedIRSAStoreName(s.framework),
 		},
 	}
 	_, err := controllerutil.CreateOrUpdate(context.Background(), s.framework.CRClient, secretStore, func() error {
-		secretStore.Spec.Provider = &esv1alpha1.SecretStoreProvider{
-			AWS: &esv1alpha1.AWSProvider{
-				Service: esv1alpha1.AWSServiceParameterStore,
+		secretStore.Spec.Provider = &esv1beta1.SecretStoreProvider{
+			AWS: &esv1beta1.AWSProvider{
+				Service: esv1beta1.AWSServiceParameterStore,
 				Region:  s.region,
-				Auth: esv1alpha1.AWSAuth{
-					JWTAuth: &esv1alpha1.AWSJWTAuth{
+				Auth: esv1beta1.AWSAuth{
+					JWTAuth: &esv1beta1.AWSJWTAuth{
 						ServiceAccountRef: &esmetav1.ServiceAccountSelector{
 							Name:      s.ServiceAccountName,
 							Namespace: &s.ServiceAccountNamespace,

+ 15 - 15
e2e/suite/aws/secretsmanager/provider.go

@@ -32,7 +32,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmetav1 "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	"github.com/external-secrets/external-secrets/e2e/framework/log"
@@ -68,14 +68,14 @@ func NewProvider(f *framework.Framework, kid, sak, region, saName, saNamespace s
 	}
 
 	BeforeEach(func() {
-		common.SetupStaticStore(f, kid, sak, region, esv1alpha1.AWSServiceSecretsManager)
+		common.SetupStaticStore(f, kid, sak, region, esv1beta1.AWSServiceSecretsManager)
 		prov.SetupReferencedIRSAStore()
 		prov.SetupMountedIRSAStore()
 	})
 
 	AfterEach(func() {
 		// Cleanup ClusterSecretStore
-		err := prov.framework.CRClient.Delete(context.Background(), &esv1alpha1.ClusterSecretStore{
+		err := prov.framework.CRClient.Delete(context.Background(), &esv1beta1.ClusterSecretStore{
 			ObjectMeta: metav1.ObjectMeta{
 				Name: common.ReferencedIRSAStoreName(f),
 			},
@@ -133,17 +133,17 @@ func (s *Provider) DeleteSecret(key string) {
 // MountedIRSAStore is a SecretStore without auth config
 // ESO relies on the pod-mounted ServiceAccount when using this store.
 func (s *Provider) SetupMountedIRSAStore() {
-	secretStore := &esv1alpha1.SecretStore{
+	secretStore := &esv1beta1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      common.MountedIRSAStoreName(s.framework),
 			Namespace: s.framework.Namespace.Name,
 		},
-		Spec: esv1alpha1.SecretStoreSpec{
-			Provider: &esv1alpha1.SecretStoreProvider{
-				AWS: &esv1alpha1.AWSProvider{
-					Service: esv1alpha1.AWSServiceSecretsManager,
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				AWS: &esv1beta1.AWSProvider{
+					Service: esv1beta1.AWSServiceSecretsManager,
 					Region:  s.region,
-					Auth:    esv1alpha1.AWSAuth{},
+					Auth:    esv1beta1.AWSAuth{},
 				},
 			},
 		},
@@ -156,18 +156,18 @@ func (s *Provider) SetupMountedIRSAStore() {
 // that references a (IRSA-) ServiceAccount in the default namespace.
 func (s *Provider) SetupReferencedIRSAStore() {
 	log.Logf("creating IRSA ClusterSecretStore %s", s.framework.Namespace.Name)
-	secretStore := &esv1alpha1.ClusterSecretStore{
+	secretStore := &esv1beta1.ClusterSecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: common.ReferencedIRSAStoreName(s.framework),
 		},
 	}
 	_, err := controllerutil.CreateOrUpdate(context.Background(), s.framework.CRClient, secretStore, func() error {
-		secretStore.Spec.Provider = &esv1alpha1.SecretStoreProvider{
-			AWS: &esv1alpha1.AWSProvider{
-				Service: esv1alpha1.AWSServiceSecretsManager,
+		secretStore.Spec.Provider = &esv1beta1.SecretStoreProvider{
+			AWS: &esv1beta1.AWSProvider{
+				Service: esv1beta1.AWSServiceSecretsManager,
 				Region:  s.region,
-				Auth: esv1alpha1.AWSAuth{
-					JWTAuth: &esv1alpha1.AWSJWTAuth{
+				Auth: esv1beta1.AWSAuth{
+					JWTAuth: &esv1beta1.AWSJWTAuth{
 						ServiceAccountRef: &esmetav1.ServiceAccountSelector{
 							Name:      s.ServiceAccountName,
 							Namespace: &s.ServiceAccountNamespace,

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

@@ -20,7 +20,7 @@ import (
 	v1 "k8s.io/api/core/v1"
 
 	// nolint
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
 
@@ -52,10 +52,10 @@ var _ = Describe("[azure]", Label("azure", "keyvault", "cert"), func() {
 					secretKey: certBytes,
 				},
 			}
-			tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+			tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 				{
 					SecretKey: secretKey,
-					RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+					RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 						Key: "cert/" + certName,
 					},
 				},

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

@@ -22,7 +22,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	v1 "k8s.io/api/core/v1"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
 
@@ -55,10 +55,10 @@ var _ = Describe("[azure]", Label("azure", "keyvault", "key"), func() {
 					secretKey: keyBytes,
 				},
 			}
-			tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+			tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 				{
 					SecretKey: secretKey,
-					RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+					RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 						Key: "key/" + keyName,
 					},
 				},

+ 6 - 6
e2e/suite/azure/provider.go

@@ -28,7 +28,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	utilpointer "k8s.io/utils/pointer"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
@@ -190,17 +190,17 @@ func (s *azureProvider) CreateSecretStore() {
 	err := s.framework.CRClient.Create(context.Background(), azureCreds)
 	Expect(err).ToNot(HaveOccurred())
 
-	secretStore := &esv1alpha1.SecretStore{
+	secretStore := &esv1beta1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      s.framework.Namespace.Name,
 			Namespace: s.framework.Namespace.Name,
 		},
-		Spec: esv1alpha1.SecretStoreSpec{
-			Provider: &esv1alpha1.SecretStoreProvider{
-				AzureKV: &esv1alpha1.AzureKVProvider{
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				AzureKV: &esv1beta1.AzureKVProvider{
 					TenantID: &s.tenantID,
 					VaultURL: &s.vaultURL,
-					AuthSecretRef: &esv1alpha1.AzureKVAuth{
+					AuthSecretRef: &esv1beta1.AzureKVAuth{
 						ClientID: &esmeta.SecretKeySelector{
 							Name: "provider-secret",
 							Key:  "client-id",

+ 69 - 33
e2e/suite/common/common.go

@@ -18,7 +18,7 @@ import (
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
 
@@ -48,16 +48,16 @@ func SimpleDataSync(f *framework.Framework) (string, func(*framework.TestCase))
 				secretKey2: []byte(secretValue),
 			},
 		}
-		tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{
 				SecretKey: secretKey1,
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key: secretKey1,
 				},
 			},
 			{
 				SecretKey: secretKey2,
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key: secretKey2,
 				},
 			},
@@ -81,10 +81,10 @@ func SyncWithoutTargetName(f *framework.Framework) (string, func(*framework.Test
 			},
 		}
 		tc.ExternalSecret.Spec.Target.Name = ""
-		tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{
 				SecretKey: secretKey1,
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key: secretKey1,
 				},
 			},
@@ -111,17 +111,17 @@ func JSONDataWithProperty(f *framework.Framework) (string, func(*framework.TestC
 				secretKey2: []byte("bar2-val"),
 			},
 		}
-		tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{
 				SecretKey: secretKey1,
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key:      secretKey1,
 					Property: "foo1",
 				},
 			},
 			{
 				SecretKey: secretKey2,
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key:      secretKey2,
 					Property: "bar2",
 				},
@@ -146,10 +146,10 @@ func JSONDataWithoutTargetName(f *framework.Framework) (string, func(*framework.
 			},
 		}
 		tc.ExternalSecret.Spec.Target.Name = ""
-		tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{
 				SecretKey: secretKey,
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key:      secretKey,
 					Property: "foo",
 				},
@@ -184,8 +184,8 @@ func JSONDataWithTemplate(f *framework.Framework) (string, func(*framework.TestC
 				"my-data": []byte(`executed: foo1-val|bar2-val`),
 			},
 		}
-		tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
-			Metadata: esv1alpha1.ExternalSecretTemplateMetadata{
+		tc.ExternalSecret.Spec.Target.Template = &esv1beta1.ExternalSecretTemplate{
+			Metadata: esv1beta1.ExternalSecretTemplateMetadata{
 				Annotations: map[string]string{
 					"example": "annotation",
 				},
@@ -197,17 +197,17 @@ func JSONDataWithTemplate(f *framework.Framework) (string, func(*framework.TestC
 				"my-data": "executed: {{ .one | toString }}|{{ .two | toString }}",
 			},
 		}
-		tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{
 				SecretKey: "one",
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key:      secretKey1,
 					Property: "foo1",
 				},
 			},
 			{
 				SecretKey: "two",
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key:      secretKey2,
 					Property: "bar2",
 				},
@@ -216,6 +216,40 @@ func JSONDataWithTemplate(f *framework.Framework) (string, func(*framework.TestC
 	}
 }
 
+// This case creates two secrets with json values and syncs them using a single .Spec.DataFrom.Find block.
+func JSONFindSync(f *framework.Framework) (string, func(*framework.TestCase)) {
+	return "[common] should sync secrets with dataFrom.Find.Name", func(tc *framework.TestCase) {
+		secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one")
+		secretKey2 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one-too")
+		targetSecretKey1 := "name"
+		targetSecretValue1 := "great-name"
+		targetSecretKey2 := "surname"
+		targetSecretValue2 := "great-surname"
+		secretValue1 := fmt.Sprintf("{\"%s\":\"%s\"}", targetSecretKey1, targetSecretValue1)
+		secretValue2 := fmt.Sprintf("{\"%s\":\"%s\"}", targetSecretKey2, targetSecretValue2)
+		tc.Secrets = map[string]string{
+			secretKey1: secretValue1,
+			secretKey2: secretValue2,
+		}
+		tc.ExpectedSecret = &v1.Secret{
+			Type: v1.SecretTypeOpaque,
+			Data: map[string][]byte{
+				secretKey1: []byte(secretValue1),
+				secretKey2: []byte(secretValue2),
+			},
+		}
+		tc.ExternalSecret.Spec.DataFrom = []esv1beta1.ExternalSecretDataFromRemoteRef{
+			{
+				Find: &esv1beta1.ExternalSecretFind{
+					Name: &esv1beta1.FindName{
+						RegExp: "one",
+					},
+				},
+			},
+		}
+	}
+}
+
 // This case creates one secret with json values and syncs them using a single .Spec.DataFrom block.
 func JSONDataFromSync(f *framework.Framework) (string, func(*framework.TestCase)) {
 	return "[common] should sync secrets with dataFrom", func(tc *framework.TestCase) {
@@ -235,9 +269,11 @@ func JSONDataFromSync(f *framework.Framework) (string, func(*framework.TestCase)
 				targetSecretKey2: []byte(targetSecretValue2),
 			},
 		}
-		tc.ExternalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
+		tc.ExternalSecret.Spec.DataFrom = []esv1beta1.ExternalSecretDataFromRemoteRef{
 			{
-				Key: secretKey1,
+				Extract: &esv1beta1.ExternalSecretDataRemoteRef{
+					Key: secretKey1,
+				},
 			},
 		}
 	}
@@ -273,17 +309,17 @@ func NestedJSONWithGJSON(f *framework.Framework) (string, func(*framework.TestCa
 				targetSecretKey2: []byte(targetSecretValue2),
 			},
 		}
-		tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{
 				SecretKey: targetSecretKey1,
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key:      secretKey1,
 					Property: "name.first",
 				},
 			},
 			{
 				SecretKey: targetSecretKey2,
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key:      secretKey1,
 					Property: "friends.1.first",
 				},
@@ -311,17 +347,17 @@ func DockerJSONConfig(f *framework.Framework) (string, func(*framework.TestCase)
 			},
 		}
 
-		tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{
 				SecretKey: "mysecret",
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key:      cloudSecretName,
 					Property: "dockerconfig",
 				},
 			},
 		}
 
-		tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
+		tc.ExternalSecret.Spec.Target.Template = &esv1beta1.ExternalSecretTemplate{
 			Data: map[string]string{
 				dockerConfigJSONKey: mysecretToStringTemplating,
 			},
@@ -349,17 +385,17 @@ func DataPropertyDockerconfigJSON(f *framework.Framework) (string, func(*framewo
 			},
 		}
 
-		tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{
 				SecretKey: "mysecret",
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key:      cloudSecretName,
 					Property: "dockerconfig",
 				},
 			},
 		}
 
-		tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
+		tc.ExternalSecret.Spec.Target.Template = &esv1beta1.ExternalSecretTemplate{
 			Type: v1.SecretTypeDockerConfigJson,
 			Data: map[string]string{
 				dockerConfigJSONKey: mysecretToStringTemplating,
@@ -423,16 +459,16 @@ func SSHKeySync(f *framework.Framework) (string, func(*framework.TestCase)) {
 			},
 		}
 
-		tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{
 				SecretKey: "mysecret",
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key: sshSecretName,
 				},
 			},
 		}
 
-		tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
+		tc.ExternalSecret.Spec.Target.Template = &esv1beta1.ExternalSecretTemplate{
 			Type: v1.SecretTypeSSHAuth,
 			Data: map[string]string{
 				sshPrivateKey: mysecretToStringTemplating,
@@ -495,17 +531,17 @@ func SSHKeySyncDataProperty(f *framework.Framework) (string, func(*framework.Tes
 			},
 		}
 
-		tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{
 				SecretKey: "mysecret",
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key:      cloudSecretName,
 					Property: "ssh-auth",
 				},
 			},
 		}
 
-		tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
+		tc.ExternalSecret.Spec.Target.Template = &esv1beta1.ExternalSecretTemplate{
 			Type: v1.SecretTypeSSHAuth,
 			Data: map[string]string{
 				sshPrivateKey: mysecretToStringTemplating,

+ 6 - 5
e2e/suite/gcp/gcp.go

@@ -24,7 +24,7 @@ import (
 	p12 "software.sslmate.com/src/go-pkcs12"
 
 	// nolint
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	"github.com/external-secrets/external-secrets/e2e/suite/common"
 )
@@ -134,17 +134,18 @@ x6HaRh+EUwU51von6M9lEF9/p5Q=
 		},
 	}
 
-	tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+	tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 		{
 			SecretKey: "mysecret",
-			RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+			RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 				Key: cloudSecretName,
 			},
 		},
 	}
 
-	tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
-		Type: v1.SecretTypeTLS,
+	tc.ExternalSecret.Spec.Target.Template = &esv1beta1.ExternalSecretTemplate{
+		Type:          v1.SecretTypeTLS,
+		EngineVersion: esv1beta1.TemplateEngineV1,
 		Data: map[string]string{
 			"tls.crt": "{{ .mysecret | pkcs12cert | pemCertificate }}",
 			"tls.key": "{{ .mysecret | pkcs12key | pemPrivateKey }}",

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

@@ -19,7 +19,7 @@ import (
 
 	// nolint
 	// . "github.com/onsi/gomega"
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	"github.com/external-secrets/external-secrets/e2e/framework/addon"
 	"github.com/external-secrets/external-secrets/e2e/suite/common"
@@ -105,7 +105,7 @@ func usePodIDESReference(tc *framework.TestCase) {
 
 func useSpecifcSAESReference(prov *GcpProvider) func(*framework.TestCase) {
 	return func(tc *framework.TestCase) {
-		tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.ClusterSecretStoreKind
+		tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1beta1.ClusterSecretStoreKind
 		tc.ExternalSecret.Spec.SecretStoreRef.Name = prov.SAClusterSecretStoreName()
 	}
 }

+ 14 - 14
e2e/suite/gcp/provider.go

@@ -33,7 +33,7 @@ import (
 	utilpointer "k8s.io/utils/pointer"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	gcpsm "github.com/external-secrets/external-secrets/pkg/provider/gcp/secretmanager"
@@ -145,16 +145,16 @@ func (s *GcpProvider) DeleteSecret(key string) {
 	Expect(err).ToNot(HaveOccurred())
 }
 
-func makeStore(s *GcpProvider) *esv1alpha1.SecretStore {
-	return &esv1alpha1.SecretStore{
+func makeStore(s *GcpProvider) *esv1beta1.SecretStore {
+	return &esv1beta1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      s.framework.Namespace.Name,
 			Namespace: s.framework.Namespace.Name,
 		},
-		Spec: esv1alpha1.SecretStoreSpec{
+		Spec: esv1beta1.SecretStoreSpec{
 			Controller: s.controllerClass,
-			Provider: &esv1alpha1.SecretStoreProvider{
-				GCPSM: &esv1alpha1.GCPSMProvider{
+			Provider: &esv1beta1.SecretStoreProvider{
+				GCPSM: &esv1beta1.GCPSMProvider{
 					ProjectID: s.projectID,
 				},
 			},
@@ -178,8 +178,8 @@ func (s *GcpProvider) CreateSAKeyStore(ns string) {
 		Expect(err).ToNot(HaveOccurred())
 	}
 	secretStore := makeStore(s)
-	secretStore.Spec.Provider.GCPSM.Auth = esv1alpha1.GCPSMAuth{
-		SecretRef: &esv1alpha1.GCPSMAuthSecretRef{
+	secretStore.Spec.Provider.GCPSM.Auth = esv1beta1.GCPSMAuth{
+		SecretRef: &esv1beta1.GCPSMAuthSecretRef{
 			SecretAccessKey: esmeta.SecretKeySelector{
 				Name: staticCredentialsSecretName,
 				Key:  "secret-access-credentials",
@@ -202,18 +202,18 @@ func (s *GcpProvider) SAClusterSecretStoreName() string {
 }
 
 func (s *GcpProvider) CreateSpecifcSASecretStore(ns string) {
-	clusterSecretStore := &esv1alpha1.ClusterSecretStore{
+	clusterSecretStore := &esv1beta1.ClusterSecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: s.SAClusterSecretStoreName(),
 		},
 	}
 	_, err := controllerutil.CreateOrUpdate(context.Background(), s.framework.CRClient, clusterSecretStore, func() error {
 		clusterSecretStore.Spec.Controller = s.controllerClass
-		clusterSecretStore.Spec.Provider = &esv1alpha1.SecretStoreProvider{
-			GCPSM: &esv1alpha1.GCPSMProvider{
+		clusterSecretStore.Spec.Provider = &esv1beta1.SecretStoreProvider{
+			GCPSM: &esv1beta1.GCPSMProvider{
 				ProjectID: s.projectID,
-				Auth: esv1alpha1.GCPSMAuth{
-					WorkloadIdentity: &esv1alpha1.GCPWorkloadIdentity{
+				Auth: esv1beta1.GCPSMAuth{
+					WorkloadIdentity: &esv1beta1.GCPWorkloadIdentity{
 						ClusterLocation: s.clusterLocation,
 						ClusterName:     s.clusterName,
 						ServiceAccountRef: esmeta.ServiceAccountSelector{
@@ -232,7 +232,7 @@ func (s *GcpProvider) CreateSpecifcSASecretStore(ns string) {
 // Cleanup removes global resources that may have been
 // created by this provider.
 func (s *GcpProvider) DeleteSpecifcSASecretStore() {
-	err := s.framework.CRClient.Delete(context.Background(), &esv1alpha1.ClusterSecretStore{
+	err := s.framework.CRClient.Delete(context.Background(), &esv1beta1.ClusterSecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: s.SAClusterSecretStoreName(),
 		},

+ 7 - 7
e2e/suite/gitlab/provider.go

@@ -27,7 +27,7 @@ import (
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
@@ -111,17 +111,17 @@ func (s *gitlabProvider) BeforeEach() {
 
 	// Create a secret store - change these values to match YAML
 	By("creating a secret store for credentials")
-	secretStore := &esv1alpha1.SecretStore{
+	secretStore := &esv1beta1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      s.framework.Namespace.Name,
 			Namespace: s.framework.Namespace.Name,
 		},
-		Spec: esv1alpha1.SecretStoreSpec{
-			Provider: &esv1alpha1.SecretStoreProvider{
-				Gitlab: &esv1alpha1.GitlabProvider{
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				Gitlab: &esv1beta1.GitlabProvider{
 					ProjectID: s.projectID,
-					Auth: esv1alpha1.GitlabAuth{
-						SecretRef: esv1alpha1.GitlabSecretRef{
+					Auth: esv1beta1.GitlabAuth{
+						SecretRef: esv1beta1.GitlabSecretRef{
 							AccessToken: esmeta.SecretKeySelector{
 								Name: "provider-secret",
 								Key:  "token",

+ 7 - 7
e2e/suite/oracle/provider.go

@@ -27,7 +27,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	utilpointer "k8s.io/utils/pointer"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
@@ -105,20 +105,20 @@ func (p *oracleProvider) BeforeEach() {
 	err := p.framework.CRClient.Create(context.Background(), OracleCreds)
 	Expect(err).ToNot(HaveOccurred())
 
-	secretStore := &esv1alpha1.SecretStore{
+	secretStore := &esv1beta1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      p.framework.Namespace.Name,
 			Namespace: p.framework.Namespace.Name,
 		},
-		Spec: esv1alpha1.SecretStoreSpec{
-			Provider: &esv1alpha1.SecretStoreProvider{
-				Oracle: &esv1alpha1.OracleProvider{
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				Oracle: &esv1beta1.OracleProvider{
 					Region: p.region,
 					Vault:  "vaultOCID",
-					Auth: &esv1alpha1.OracleAuth{
+					Auth: &esv1beta1.OracleAuth{
 						Tenancy: p.tenancy,
 						User:    p.user,
-						SecretRef: esv1alpha1.OracleSecretRef{
+						SecretRef: esv1beta1.OracleSecretRef{
 							Fingerprint: esmeta.SecretKeySelector{
 								Name: "vms-secret",
 								Key:  "keyid",

+ 6 - 6
e2e/suite/template/provider.go

@@ -23,7 +23,7 @@ import (
 	. "github.com/onsi/gomega"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
 
@@ -50,15 +50,15 @@ func (s *templateProvider) DeleteSecret(key string) {
 func (s *templateProvider) BeforeEach() {
 	// Create a secret store - change these values to match YAML
 	By("creating a secret store for credentials")
-	secretStore := &esv1alpha1.SecretStore{
+	secretStore := &esv1beta1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      s.framework.Namespace.Name,
 			Namespace: s.framework.Namespace.Name,
 		},
-		Spec: esv1alpha1.SecretStoreSpec{
-			Provider: &esv1alpha1.SecretStoreProvider{
-				Fake: &esv1alpha1.FakeProvider{
-					Data: []esv1alpha1.FakeProviderData{
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				Fake: &esv1beta1.FakeProvider{
+					Data: []esv1beta1.FakeProviderData{
 						{
 							Key:   "foo",
 							Value: "bar",

+ 13 - 11
e2e/suite/template/template.go

@@ -18,7 +18,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	v1 "k8s.io/api/core/v1"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
 
@@ -34,8 +34,8 @@ var _ = Describe("[template]", Label("template"), func() {
 
 // useTemplateV1 specifies a test case which uses the template engine v1.
 func useTemplateV1(tc *framework.TestCase) {
-	tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
-		EngineVersion: esv1alpha1.TemplateEngineV1,
+	tc.ExternalSecret.Spec.Target.Template = &esv1beta1.ExternalSecretTemplate{
+		EngineVersion: esv1beta1.TemplateEngineV1,
 		Data: map[string]string{
 			"tplv1": "executed: {{ .singlefoo | toString }}|{{ .singlebaz | toString }}",
 			"other": `{{ .foo | toString }}|{{ .bar | toString }}`,
@@ -49,8 +49,8 @@ func useTemplateV1(tc *framework.TestCase) {
 
 // useTemplateV2 specifies a test case which uses the template engine v2.
 func useTemplateV2(tc *framework.TestCase) {
-	tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
-		EngineVersion: esv1alpha1.TemplateEngineV2,
+	tc.ExternalSecret.Spec.Target.Template = &esv1beta1.ExternalSecretTemplate{
+		EngineVersion: esv1beta1.TemplateEngineV2,
 		Data: map[string]string{
 			"tplv2":     "executed: {{ .singlefoo }}|{{ .singlebaz }}",
 			"other":     `{{ .foo }}|{{ .bar }}`,
@@ -72,29 +72,31 @@ func genericTemplate(f *framework.Framework) (string, func(*framework.TestCase))
 		tc.ExpectedSecret = &v1.Secret{
 			Type: v1.SecretTypeOpaque,
 		}
-		tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{
 				SecretKey: "singlefoo",
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key: "foo",
 				},
 			},
 			{
 				SecretKey: "singlebaz",
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key: "baz",
 				},
 			},
 			{
 				SecretKey: "singlejson",
-				RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+				RemoteRef: esv1beta1.ExternalSecretDataRemoteRef{
 					Key: "json",
 				},
 			},
 		}
-		tc.ExternalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
+		tc.ExternalSecret.Spec.DataFrom = []esv1beta1.ExternalSecretDataFromRemoteRef{
 			{
-				Key: "map",
+				Extract: &esv1beta1.ExternalSecretDataRemoteRef{
+					Key: "map",
+				},
 			},
 		}
 	}

+ 18 - 18
e2e/suite/vault/provider.go

@@ -28,7 +28,7 @@ import (
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	"github.com/external-secrets/external-secrets/e2e/framework/addon"
@@ -98,16 +98,16 @@ func (s *vaultProvider) BeforeEach() {
 	s.CreateKubernetesAuthStore(v, ns)
 }
 
-func makeStore(name, ns string, v *addon.Vault) *esv1alpha1.SecretStore {
-	return &esv1alpha1.SecretStore{
+func makeStore(name, ns string, v *addon.Vault) *esv1beta1.SecretStore {
+	return &esv1beta1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      name,
 			Namespace: ns,
 		},
-		Spec: esv1alpha1.SecretStoreSpec{
-			Provider: &esv1alpha1.SecretStoreProvider{
-				Vault: &esv1alpha1.VaultProvider{
-					Version:  esv1alpha1.VaultKVStoreV2,
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				Vault: &esv1beta1.VaultProvider{
+					Version:  esv1beta1.VaultKVStoreV2,
 					Path:     &secretStorePath,
 					Server:   v.VaultURL,
 					CABundle: v.VaultServerCA,
@@ -137,8 +137,8 @@ func (s *vaultProvider) CreateCertStore(v *addon.Vault, ns string) {
 
 	By("creating an secret store for vault")
 	secretStore := makeStore(certAuthProviderName, ns, v)
-	secretStore.Spec.Provider.Vault.Auth = esv1alpha1.VaultAuth{
-		Cert: &esv1alpha1.VaultCertAuth{
+	secretStore.Spec.Provider.Vault.Auth = esv1beta1.VaultAuth{
+		Cert: &esv1beta1.VaultCertAuth{
 			ClientCert: esmeta.SecretKeySelector{
 				Name: certAuthProviderName,
 				Key:  "client_cert",
@@ -166,7 +166,7 @@ func (s vaultProvider) CreateTokenStore(v *addon.Vault, ns string) {
 	err := s.framework.CRClient.Create(context.Background(), vaultCreds)
 	Expect(err).ToNot(HaveOccurred())
 	secretStore := makeStore(s.framework.Namespace.Name, ns, v)
-	secretStore.Spec.Provider.Vault.Auth = esv1alpha1.VaultAuth{
+	secretStore.Spec.Provider.Vault.Auth = esv1beta1.VaultAuth{
 		TokenSecretRef: &esmeta.SecretKeySelector{
 			Name: "token-provider",
 			Key:  "token",
@@ -192,8 +192,8 @@ func (s vaultProvider) CreateAppRoleStore(v *addon.Vault, ns string) {
 
 	By("creating an secret store for vault")
 	secretStore := makeStore(appRoleAuthProviderName, ns, v)
-	secretStore.Spec.Provider.Vault.Auth = esv1alpha1.VaultAuth{
-		AppRole: &esv1alpha1.VaultAppRole{
+	secretStore.Spec.Provider.Vault.Auth = esv1beta1.VaultAuth{
+		AppRole: &esv1beta1.VaultAppRole{
 			Path:   v.AppRolePath,
 			RoleID: v.AppRoleID,
 			SecretRef: esmeta.SecretKeySelector{
@@ -220,9 +220,9 @@ func (s vaultProvider) CreateV1Store(v *addon.Vault, ns string) {
 	Expect(err).ToNot(HaveOccurred())
 	secretStore := makeStore(kvv1ProviderName, ns, v)
 	secretV1StorePath := "secret_v1"
-	secretStore.Spec.Provider.Vault.Version = esv1alpha1.VaultKVStoreV1
+	secretStore.Spec.Provider.Vault.Version = esv1beta1.VaultKVStoreV1
 	secretStore.Spec.Provider.Vault.Path = &secretV1StorePath
-	secretStore.Spec.Provider.Vault.Auth = esv1alpha1.VaultAuth{
+	secretStore.Spec.Provider.Vault.Auth = esv1beta1.VaultAuth{
 		TokenSecretRef: &esmeta.SecretKeySelector{
 			Name: "v1-provider",
 			Key:  "token",
@@ -245,8 +245,8 @@ func (s vaultProvider) CreateJWTStore(v *addon.Vault, ns string) {
 	err := s.framework.CRClient.Create(context.Background(), vaultCreds)
 	Expect(err).ToNot(HaveOccurred())
 	secretStore := makeStore(jwtProviderName, ns, v)
-	secretStore.Spec.Provider.Vault.Auth = esv1alpha1.VaultAuth{
-		Jwt: &esv1alpha1.VaultJwtAuth{
+	secretStore.Spec.Provider.Vault.Auth = esv1beta1.VaultAuth{
+		Jwt: &esv1beta1.VaultJwtAuth{
 			Path: v.JWTPath,
 			Role: v.JWTRole,
 			SecretRef: esmeta.SecretKeySelector{
@@ -261,8 +261,8 @@ func (s vaultProvider) CreateJWTStore(v *addon.Vault, ns string) {
 
 func (s vaultProvider) CreateKubernetesAuthStore(v *addon.Vault, ns string) {
 	secretStore := makeStore(kubernetesProviderName, ns, v)
-	secretStore.Spec.Provider.Vault.Auth = esv1alpha1.VaultAuth{
-		Kubernetes: &esv1alpha1.VaultKubernetesAuth{
+	secretStore.Spec.Provider.Vault.Auth = esv1beta1.VaultAuth{
+		Kubernetes: &esv1beta1.VaultKubernetesAuth{
 			Path: v.KubernetesAuthPath,
 			Role: v.KubernetesAuthRole,
 			ServiceAccountRef: &esmeta.ServiceAccountSelector{

+ 15 - 6
e2e/suite/vault/vault.go

@@ -19,7 +19,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	v1 "k8s.io/api/core/v1"
 
-	esapi "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esapi "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	"github.com/external-secrets/external-secrets/e2e/suite/common"
 )
@@ -40,18 +40,21 @@ var _ = Describe("[vault]", Label("vault"), func() {
 	DescribeTable("sync secrets",
 		framework.TableFunc(f, prov),
 		// uses token auth
+		framework.Compose(withTokenAuth, f, common.JSONFindSync, useTokenAuth),
 		framework.Compose(withTokenAuth, f, common.JSONDataFromSync, useTokenAuth),
 		framework.Compose(withTokenAuth, f, common.JSONDataWithProperty, useTokenAuth),
 		framework.Compose(withTokenAuth, f, common.JSONDataWithTemplate, useTokenAuth),
 		framework.Compose(withTokenAuth, f, common.DataPropertyDockerconfigJSON, useTokenAuth),
 		framework.Compose(withTokenAuth, f, common.JSONDataWithoutTargetName, useTokenAuth),
 		// use cert auth
+		framework.Compose(withCertAuth, f, common.JSONFindSync, useCertAuth),
 		framework.Compose(withCertAuth, f, common.JSONDataFromSync, useCertAuth),
 		framework.Compose(withCertAuth, f, common.JSONDataWithProperty, useCertAuth),
 		framework.Compose(withCertAuth, f, common.JSONDataWithTemplate, useCertAuth),
 		framework.Compose(withCertAuth, f, common.DataPropertyDockerconfigJSON, useCertAuth),
 		framework.Compose(withCertAuth, f, common.JSONDataWithoutTargetName, useCertAuth),
 		// use approle auth
+		framework.Compose(withApprole, f, common.JSONFindSync, useApproleAuth),
 		framework.Compose(withApprole, f, common.JSONDataFromSync, useApproleAuth),
 		framework.Compose(withApprole, f, common.JSONDataWithProperty, useApproleAuth),
 		framework.Compose(withApprole, f, common.JSONDataWithTemplate, useApproleAuth),
@@ -64,12 +67,14 @@ var _ = Describe("[vault]", Label("vault"), func() {
 		framework.Compose(withV1, f, common.DataPropertyDockerconfigJSON, useV1Provider),
 		framework.Compose(withV1, f, common.JSONDataWithoutTargetName, useV1Provider),
 		// use jwt provider
+		framework.Compose(withJWT, f, common.JSONFindSync, useJWTProvider),
 		framework.Compose(withJWT, f, common.JSONDataFromSync, useJWTProvider),
 		framework.Compose(withJWT, f, common.JSONDataWithProperty, useJWTProvider),
 		framework.Compose(withJWT, f, common.JSONDataWithTemplate, useJWTProvider),
 		framework.Compose(withJWT, f, common.DataPropertyDockerconfigJSON, useJWTProvider),
 		framework.Compose(withJWT, f, common.JSONDataWithoutTargetName, useJWTProvider),
 		// use kubernetes provider
+		framework.Compose(withK8s, f, common.JSONFindSync, useKubernetesProvider),
 		framework.Compose(withK8s, f, common.JSONDataFromSync, useKubernetesProvider),
 		framework.Compose(withK8s, f, common.JSONDataWithProperty, useKubernetesProvider),
 		framework.Compose(withK8s, f, common.JSONDataWithTemplate, useKubernetesProvider),
@@ -168,9 +173,11 @@ func testDataFromJSONWithoutProperty(tc *framework.TestCase) {
 			"foo": []byte(`{"nested":{"bar":"mysecret","baz":"bang"}}`),
 		},
 	}
-	tc.ExternalSecret.Spec.DataFrom = []esapi.ExternalSecretDataRemoteRef{
+	tc.ExternalSecret.Spec.DataFrom = []esapi.ExternalSecretDataFromRemoteRef{
 		{
-			Key: secretKey,
+			Extract: &esapi.ExternalSecretDataRemoteRef{
+				Key: secretKey,
+			},
 		},
 	}
 }
@@ -188,10 +195,12 @@ func testDataFromJSONWithProperty(tc *framework.TestCase) {
 			"baz": []byte(`bang`),
 		},
 	}
-	tc.ExternalSecret.Spec.DataFrom = []esapi.ExternalSecretDataRemoteRef{
+	tc.ExternalSecret.Spec.DataFrom = []esapi.ExternalSecretDataFromRemoteRef{
 		{
-			Key:      secretKey,
-			Property: "foo.nested",
+			Extract: &esapi.ExternalSecretDataRemoteRef{
+				Key:      secretKey,
+				Property: "foo.nested",
+			},
 		},
 	}
 }

+ 11 - 1
pkg/controllers/externalsecret/externalsecret_controller.go

@@ -46,6 +46,8 @@ const (
 	requeueAfter = time.Second * 30
 
 	errGetES                 = "could not get ExternalSecret"
+	errConvert               = "could not apply conversion strategy to keys: %v"
+	errFindSecretKey         = "could not find secret %v: %v"
 	errUpdateSecret          = "could not update Secret"
 	errPatchStatus           = "unable to patch status"
 	errGetSecretStore        = "could not get SecretStore %q, %w"
@@ -400,13 +402,21 @@ func (r *Reconciler) getProviderSecretData(ctx context.Context, providerClient e
 		if remoteRef.Find != nil {
 			secretMap, err = providerClient.GetAllSecrets(ctx, *remoteRef.Find)
 			if err != nil {
-				return nil, fmt.Errorf(errGetSecretKey, remoteRef.Extract.Key, externalSecret.Name, err)
+				return nil, fmt.Errorf(errFindSecretKey, externalSecret.Name, err)
+			}
+			secretMap, err = utils.ConvertKeys(remoteRef.Find.ConversionStrategy, secretMap)
+			if err != nil {
+				return nil, fmt.Errorf(errConvert, err)
 			}
 		} else if remoteRef.Extract != nil {
 			secretMap, err = providerClient.GetSecretMap(ctx, *remoteRef.Extract)
 			if err != nil {
 				return nil, fmt.Errorf(errGetSecretKey, remoteRef.Extract.Key, externalSecret.Name, err)
 			}
+			secretMap, err = utils.ConvertKeys(remoteRef.Extract.ConversionStrategy, secretMap)
+			if err != nil {
+				return nil, fmt.Errorf(errConvert, err)
+			}
 		}
 
 		providerData = utils.MergeByteMap(providerData, secretMap)

+ 34 - 0
pkg/provider/vault/fake/vault.go

@@ -16,6 +16,8 @@ package fake
 
 import (
 	"context"
+	"net/url"
+	"strings"
 
 	vault "github.com/hashicorp/vault/api"
 )
@@ -40,6 +42,17 @@ func NewMockNewRequestFn(req *vault.Request) MockNewRequestFn {
 	}
 }
 
+func NewMockNewRequestListFn(req *vault.Request) MockNewRequestFn {
+	return func(method, requestPath string) *vault.Request {
+		urlPath := url.URL{
+			Path: requestPath,
+		}
+		req.URL = &urlPath
+		req.Params = make(url.Values)
+		return req
+	}
+}
+
 // An RequestFn operates on the supplied Request. You might use an RequestFn to
 // test or update the contents of an Request.
 type RequestFn func(req *vault.Request) error
@@ -55,6 +68,27 @@ func NewMockRawRequestWithContextFn(res *vault.Response, err error, ofn ...Reque
 	}
 }
 
+type VaultListResponse struct {
+	Metadata *vault.Response
+	Data     *vault.Response
+}
+
+func NewMockRawRequestListWithContextFn(res map[string]VaultListResponse, err error) MockRawRequestWithContextFn {
+	return func(_ context.Context, r *vault.Request) (*vault.Response, error) {
+		pathList := strings.Split(r.URL.Path, "/")
+		path := "default"
+		if pathList[4] != "" {
+			path = strings.Join(pathList[4:], "/")
+		}
+		if strings.Contains(r.URL.Path, "metadata") {
+			resp := res[path].Metadata
+			return resp, err
+		}
+		resp := res[path].Data
+		return resp, err
+	}
+}
+
 func NewSetTokenFn(ofn ...func(v string)) MockSetTokenFn {
 	return func(v string) {
 		for _, fn := range ofn {

+ 172 - 21
pkg/provider/vault/vault.go

@@ -24,6 +24,7 @@ import (
 	"io/ioutil"
 	"net/http"
 	"os"
+	"regexp"
 	"strconv"
 	"strings"
 
@@ -48,25 +49,26 @@ var (
 const (
 	serviceAccTokenPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
 
-	errVaultStore         = "received invalid Vault SecretStore resource: %w"
-	errVaultClient        = "cannot setup new vault client: %w"
-	errVaultCert          = "cannot set Vault CA certificate: %w"
-	errReadSecret         = "cannot read secret data from Vault: %w"
-	errAuthFormat         = "cannot initialize Vault client: no valid auth method specified"
-	errInvalidCredentials = "invalid vault credentials: %w"
-	errDataField          = "failed to find data field"
-	errJSONUnmarshall     = "failed to unmarshall JSON"
-	errSecretFormat       = "secret data not in expected format"
-	errUnexpectedKey      = "unexpected key in data: %s"
-	errVaultToken         = "cannot parse Vault authentication token: %w"
-	errVaultReqParams     = "cannot set Vault request parameters: %w"
-	errVaultRequest       = "error from Vault request: %w"
-	errVaultResponse      = "cannot parse Vault response: %w"
-	errServiceAccount     = "cannot read Kubernetes service account token from file system: %w"
-
-	errGetKubeSA        = "cannot get Kubernetes service account %q: %w"
-	errGetKubeSASecrets = "cannot find secrets bound to service account: %q"
-	errGetKubeSANoToken = "cannot find token in secrets bound to service account: %q"
+	errVaultStore           = "received invalid Vault SecretStore resource: %w"
+	errVaultClient          = "cannot setup new vault client: %w"
+	errVaultCert            = "cannot set Vault CA certificate: %w"
+	errReadSecret           = "cannot read secret data from Vault: %w"
+	errAuthFormat           = "cannot initialize Vault client: no valid auth method specified"
+	errInvalidCredentials   = "invalid vault credentials: %w"
+	errDataField            = "failed to find data field"
+	errJSONUnmarshall       = "failed to unmarshall JSON"
+	errPathInvalid          = "provided Path isn't a valid kv v2 path"
+	errSecretFormat         = "secret data not in expected format"
+	errUnexpectedKey        = "unexpected key in data: %s"
+	errVaultToken           = "cannot parse Vault authentication token: %w"
+	errVaultReqParams       = "cannot set Vault request parameters: %w"
+	errVaultRequest         = "error from Vault request: %w"
+	errVaultResponse        = "cannot parse Vault response: %w"
+	errServiceAccount       = "cannot read Kubernetes service account token from file system: %w"
+	errUnsupportedKvVersion = "cannot perform find operations with kv version v1"
+	errGetKubeSA            = "cannot get Kubernetes service account %q: %w"
+	errGetKubeSASecrets     = "cannot find secrets bound to service account: %q"
+	errGetKubeSANoToken     = "cannot find token in secrets bound to service account: %q"
 
 	errGetKubeSecret = "cannot get Kubernetes secret %q: %w"
 	errSecretKeyFmt  = "cannot find secret data for key: %q"
@@ -229,9 +231,145 @@ func (c *connector) ValidateStore(store esv1beta1.GenericStore) error {
 }
 
 // Empty GetAllSecrets.
+// GetAllSecrets
+// First load all secrets from secretStore path configuration.
+// Then, gets secrets from a matching name or matching custom_metadata.
 func (v *client) GetAllSecrets(ctx context.Context, ref esv1beta1.ExternalSecretFind) (map[string][]byte, error) {
-	// TO be implemented
-	return nil, fmt.Errorf("GetAllSecrets not implemented")
+	if v.store.Version == esv1beta1.VaultKVStoreV1 {
+		return nil, errors.New(errUnsupportedKvVersion)
+	}
+	searchPath := ""
+	if ref.Path != nil {
+		searchPath = *ref.Path + "/"
+	}
+	potentialSecrets, err := v.listSecrets(ctx, searchPath)
+	if err != nil {
+		return nil, err
+	}
+	if ref.Name != nil {
+		return v.findSecretsFromName(ctx, potentialSecrets, *ref.Name, searchPath)
+	}
+	return v.findSecretsFromTags(ctx, potentialSecrets, ref.Tags, searchPath)
+}
+
+func (v *client) findSecretsFromTags(ctx context.Context, candidates []string, tags map[string]string, removeFromName string) (map[string][]byte, error) {
+	secrets := make(map[string][]byte)
+	for _, name := range candidates {
+		match := true
+		metadata, err := v.readSecretMetadata(ctx, name)
+		if err != nil {
+			return nil, err
+		}
+		for tk, tv := range tags {
+			p, ok := metadata[tk]
+			if !ok || p != tv {
+				match = false
+				break
+			}
+		}
+		if match {
+			secret, err := v.GetSecret(ctx, esv1beta1.ExternalSecretDataRemoteRef{Key: name})
+			if err != nil {
+				return nil, err
+			}
+			if removeFromName != "" {
+				name = strings.TrimPrefix(name, removeFromName)
+			}
+			secrets[name] = secret
+		}
+	}
+	return secrets, nil
+}
+
+func (v *client) findSecretsFromName(ctx context.Context, candidates []string, ref esv1beta1.FindName, removeFromName string) (map[string][]byte, error) {
+	secrets := make(map[string][]byte)
+	for _, name := range candidates {
+		ok, err := regexp.MatchString(ref.RegExp, name)
+		if err != nil {
+			return nil, err
+		}
+		if ok {
+			secret, err := v.GetSecret(ctx, esv1beta1.ExternalSecretDataRemoteRef{Key: name})
+			if err != nil {
+				return nil, err
+			}
+			if removeFromName != "" {
+				name = strings.TrimPrefix(name, removeFromName)
+			}
+			secrets[name] = secret
+		}
+	}
+	return secrets, nil
+}
+
+func (v *client) listSecrets(ctx context.Context, path string) ([]string, error) {
+	secrets := make([]string, 0)
+	url, err := v.buildMetadataPath(path)
+	if err != nil {
+		return nil, err
+	}
+	r := v.client.NewRequest(http.MethodGet, url)
+	r.Params.Set("list", "true")
+	resp, err := v.client.RawRequestWithContext(ctx, r)
+	if err != nil {
+		return nil, fmt.Errorf(errReadSecret, err)
+	}
+	secret, parseErr := vault.ParseSecret(resp.Body)
+	if parseErr != nil {
+		return nil, parseErr
+	}
+	t, ok := secret.Data["keys"]
+	if !ok {
+		return nil, nil
+	}
+	paths := t.([]interface{})
+	for _, p := range paths {
+		strPath := p.(string)
+		fullPath := path + strPath // because path always ends with a /
+		if path == "" {
+			fullPath = strPath
+		}
+		// Recurrently find secrets
+		if !strings.HasSuffix(p.(string), "/") {
+			secrets = append(secrets, fullPath)
+		} else {
+			partial, err := v.listSecrets(ctx, fullPath)
+			if err != nil {
+				return nil, err
+			}
+			secrets = append(secrets, partial...)
+		}
+	}
+	return secrets, nil
+}
+
+func (v *client) readSecretMetadata(ctx context.Context, path string) (map[string]string, error) {
+	metadata := make(map[string]string)
+	url, err := v.buildMetadataPath(path)
+	if err != nil {
+		return nil, err
+	}
+	r := v.client.NewRequest(http.MethodGet, url)
+	resp, err := v.client.RawRequestWithContext(ctx, r)
+	if err != nil {
+		return nil, fmt.Errorf(errReadSecret, err)
+	}
+	secret, parseErr := vault.ParseSecret(resp.Body)
+	if parseErr != nil {
+		return nil, parseErr
+	}
+	t, ok := secret.Data["custom_metadata"]
+	if !ok {
+		return nil, nil
+	}
+	d, ok := t.(map[string]interface{})
+	if !ok {
+		return metadata, nil
+	}
+	for k, v := range d {
+		metadata[k] = v.(string)
+	}
+	return metadata, nil
 }
 
 // GetSecret supports two types:
@@ -338,6 +476,19 @@ func (v *client) Validate() error {
 	return nil
 }
 
+func (v *client) buildMetadataPath(path string) (string, error) {
+	var url string
+	if v.store.Path == nil && !strings.Contains(path, "data") {
+		return "", fmt.Errorf(errPathInvalid)
+	}
+	if v.store.Path == nil {
+		path = strings.Replace(path, "data", "metadata", 1)
+		url = fmt.Sprintf("/v1/%s", path)
+	} else {
+		url = fmt.Sprintf("/v1/%s/metadata/%s", *v.store.Path, path)
+	}
+	return url, nil
+}
 func (v *client) buildPath(path string) string {
 	optionalMount := v.store.Path
 	origPath := strings.Split(path, "/")

+ 230 - 0
pkg/provider/vault/vault_test.go

@@ -186,6 +186,24 @@ func newVaultResponseWithData(data map[string]interface{}) *vault.Response {
 	})
 }
 
+func newVaultResponseWithMetadata(content map[string]interface{}) map[string]fake.VaultListResponse {
+	ans := make(map[string]fake.VaultListResponse)
+	for k, v := range content {
+		t := v.(map[string]interface{})
+		m := t["metadata"].(map[string]interface{})
+		listResponse := fake.VaultListResponse{
+			Data: newVaultResponse(&vault.Secret{
+				Data: t,
+			}),
+			Metadata: newVaultResponse(&vault.Secret{
+				Data: m,
+			}),
+		}
+		ans[k] = listResponse
+	}
+	return ans
+}
+
 func newVaultTokenIDResponse(token string) *vault.Response {
 	return newVaultResponseWithData(map[string]interface{}{
 		"id": token,
@@ -983,6 +1001,218 @@ func TestGetSecretMap(t *testing.T) {
 	}
 }
 
+func TestGetAllSecrets(t *testing.T) {
+	secret1Bytes := []byte("{\"access_key\":\"access_key\",\"access_secret\":\"access_secret\"}")
+	secret2Bytes := []byte("{\"access_key\":\"access_key2\",\"access_secret\":\"access_secret2\"}")
+	path1Bytes := []byte("{\"access_key\":\"path1\",\"access_secret\":\"path1\"}")
+	path2Bytes := []byte("{\"access_key\":\"path2\",\"access_secret\":\"path2\"}")
+	tagBytes := []byte("{\"access_key\":\"unfetched\",\"access_secret\":\"unfetched\"}")
+	path := "path"
+	secret := map[string]interface{}{
+		"secret1": map[string]interface{}{
+			"data": map[string]interface{}{
+				"access_key":    "access_key",
+				"access_secret": "access_secret",
+			},
+			"metadata": map[string]interface{}{
+				"custom_metadata": map[string]interface{}{
+					"foo": "bar",
+				},
+			},
+		},
+		"secret2": map[string]interface{}{
+			"data": map[string]interface{}{
+				"access_key":    "access_key2",
+				"access_secret": "access_secret2",
+			},
+			"metadata": map[string]interface{}{
+				"custom_metadata": map[string]interface{}{
+					"foo": "baz",
+				},
+			},
+		},
+		"tag": map[string]interface{}{
+			"data": map[string]interface{}{
+				"access_key":    "unfetched",
+				"access_secret": "unfetched",
+			},
+			"metadata": map[string]interface{}{
+				"custom_metadata": map[string]interface{}{
+					"foo": "baz",
+				},
+			},
+		},
+		"path/1": map[string]interface{}{
+			"data": map[string]interface{}{
+				"access_key":    "path1",
+				"access_secret": "path1",
+			},
+			"metadata": map[string]interface{}{
+				"custom_metadata": map[string]interface{}{
+					"foo": "path",
+				},
+			},
+		},
+		"path/2": map[string]interface{}{
+			"data": map[string]interface{}{
+				"access_key":    "path2",
+				"access_secret": "path2",
+			},
+			"metadata": map[string]interface{}{
+				"custom_metadata": map[string]interface{}{
+					"foo": "path",
+				},
+			},
+		},
+		"default": map[string]interface{}{
+			"data": map[string]interface{}{
+				"empty": "true",
+			},
+			"metadata": map[string]interface{}{
+				"keys": []string{"secret1", "secret2", "tag", "path/"},
+			},
+		},
+		"path/": map[string]interface{}{
+			"data": map[string]interface{}{
+				"empty": "true",
+			},
+			"metadata": map[string]interface{}{
+				"keys": []string{"1", "2"},
+			},
+		},
+	}
+	type args struct {
+		store   *esv1beta1.VaultProvider
+		kube    kclient.Client
+		vClient Client
+		ns      string
+		data    esv1beta1.ExternalSecretFind
+	}
+
+	type want struct {
+		err error
+		val map[string][]byte
+	}
+
+	cases := map[string]struct {
+		reason string
+		args   args
+		want   want
+	}{
+		"FindByName": {
+			reason: "should map multiple secrets matching name",
+			args: args{
+				store: makeValidSecretStoreWithVersion(esv1beta1.VaultKVStoreV2).Spec.Provider.Vault,
+				vClient: &fake.VaultClient{
+					MockNewRequest: fake.NewMockNewRequestListFn(&vault.Request{}),
+					MockRawRequestWithContext: fake.NewMockRawRequestListWithContextFn(
+						newVaultResponseWithMetadata(secret), nil,
+					),
+				},
+				data: esv1beta1.ExternalSecretFind{
+					Name: &esv1beta1.FindName{
+						RegExp: "secret.*",
+					},
+				},
+			},
+			want: want{
+				err: nil,
+				val: map[string][]byte{
+					"secret1": secret1Bytes,
+					"secret2": secret2Bytes,
+				},
+			},
+		},
+		"FindByTag": {
+			reason: "should map multiple secrets matching tags",
+			args: args{
+				store: makeValidSecretStoreWithVersion(esv1beta1.VaultKVStoreV2).Spec.Provider.Vault,
+				vClient: &fake.VaultClient{
+					MockNewRequest: fake.NewMockNewRequestListFn(&vault.Request{}),
+					MockRawRequestWithContext: fake.NewMockRawRequestListWithContextFn(
+						newVaultResponseWithMetadata(secret), nil,
+					),
+				},
+				data: esv1beta1.ExternalSecretFind{
+					Tags: map[string]string{
+						"foo": "baz",
+					},
+				},
+			},
+			want: want{
+				err: nil,
+				val: map[string][]byte{
+					"tag":     tagBytes,
+					"secret2": secret2Bytes,
+				},
+			},
+		},
+		"FilterByPath": {
+			reason: "should filter secrets based on path",
+			args: args{
+				store: makeValidSecretStoreWithVersion(esv1beta1.VaultKVStoreV2).Spec.Provider.Vault,
+				vClient: &fake.VaultClient{
+					MockNewRequest: fake.NewMockNewRequestListFn(&vault.Request{}),
+					MockRawRequestWithContext: fake.NewMockRawRequestListWithContextFn(
+						newVaultResponseWithMetadata(secret), nil,
+					),
+				},
+				data: esv1beta1.ExternalSecretFind{
+					Path: &path,
+					Tags: map[string]string{
+						"foo": "path",
+					},
+				},
+			},
+			want: want{
+				err: nil,
+				val: map[string][]byte{
+					"1": path1Bytes,
+					"2": path2Bytes,
+				},
+			},
+		},
+		"FailIfKv1": {
+			reason: "should not work if using kv1 store",
+			args: args{
+				store: makeValidSecretStoreWithVersion(esv1beta1.VaultKVStoreV1).Spec.Provider.Vault,
+				vClient: &fake.VaultClient{
+					MockNewRequest: fake.NewMockNewRequestListFn(&vault.Request{}),
+					MockRawRequestWithContext: fake.NewMockRawRequestListWithContextFn(
+						newVaultResponseWithMetadata(secret), nil,
+					),
+				},
+				data: esv1beta1.ExternalSecretFind{
+					Tags: map[string]string{
+						"foo": "baz",
+					},
+				},
+			},
+			want: want{
+				err: errors.New(errUnsupportedKvVersion),
+			},
+		},
+	}
+
+	for name, tc := range cases {
+		t.Run(name, func(t *testing.T) {
+			vStore := &client{
+				kube:      tc.args.kube,
+				client:    tc.args.vClient,
+				store:     tc.args.store,
+				namespace: tc.args.ns,
+			}
+			val, err := vStore.GetAllSecrets(context.Background(), tc.args.data)
+			if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" {
+				t.Errorf("\n%s\nvault.GetSecretMap(...): -want error, +got error:\n%s", tc.reason, diff)
+			}
+			if diff := cmp.Diff(tc.want.val, val); diff != "" {
+				t.Errorf("\n%s\nvault.GetSecretMap(...): -want val, +got val:\n%s", tc.reason, diff)
+			}
+		})
+	}
+}
+
 func TestGetSecretPath(t *testing.T) {
 	storeV2 := makeValidSecretStore()
 	storeV2NoPath := storeV2.DeepCopy()

+ 35 - 0
pkg/utils/utils.go

@@ -21,6 +21,7 @@ import (
 	"fmt"
 	"reflect"
 	"strings"
+	"unicode"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
@@ -34,6 +35,40 @@ func MergeByteMap(dst, src map[string][]byte) map[string][]byte {
 	return dst
 }
 
+// ConvertKeys converts a secret map into a valid key.
+// Replaces any non-alphanumeric characters depending on convert strategy.
+func ConvertKeys(strategy esv1beta1.ExternalSecretConversionStrategy, in map[string][]byte) (map[string][]byte, error) {
+	out := make(map[string][]byte)
+	for k, v := range in {
+		rs := []rune(k)
+		newName := make([]string, len(rs))
+		for rk, rv := range rs {
+			if !unicode.IsNumber(rv) &&
+				!unicode.IsLetter(rv) &&
+				rv != '-' &&
+				rv != '.' &&
+				rv != '_' {
+				switch strategy {
+				case esv1beta1.ExternalSecretConversionDefault:
+					newName[rk] = "_"
+				case esv1beta1.ExternalSecretConversionUnicode:
+					newName[rk] = fmt.Sprintf("_U%04x_", rv)
+				default:
+					return nil, fmt.Errorf("unknown conversion strategy: %s", strategy)
+				}
+			} else {
+				newName[rk] = string(rv)
+			}
+		}
+		key := strings.Join(newName, "")
+		if _, exists := out[key]; exists {
+			return nil, fmt.Errorf("secret name collision during conversion: %s", key)
+		}
+		out[key] = v
+	}
+	return out, nil
+}
+
 // MergeStringMap performs a deep clone from src to dest.
 func MergeStringMap(dest, src map[string]string) {
 	for k, v := range src {