1
0
Fork 0
mirror of https://github.com/external-secrets/external-secrets.git synced 2024-12-14 11:57:59 +00:00

Merge pull request #613 from external-secrets/getall-Secrets

GetAllSecrets CRD and Azure implementation
This commit is contained in:
paul-the-alien[bot] 2022-02-01 13:18:20 +00:00 committed by GitHub
commit ca0cda7c16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 1073 additions and 211 deletions

View file

@ -130,6 +130,54 @@ type ExternalSecretDataRemoteRef struct {
Property string `json:"property,omitempty"`
}
// ExternalSecretDataFromRemoteRef defines Provider data location.
type ExternalSecretDataFromRemoteRef struct {
// Used to select a specific version and property from the secret
// +optional
Extract ExternalSecretExtract `json:"extract,omitempty"`
// Used to find secrets based on tags or regular expressions
// +optional
Find ExternalSecretFind `json:"find,omitempty"`
}
func (ref ExternalSecretDataFromRemoteRef) GetDataRemoteRef() ExternalSecretDataRemoteRef {
return ExternalSecretDataRemoteRef{
Key: ref.Extract.Key,
Property: ref.Extract.Property,
Version: ref.Extract.Version,
}
}
type ExternalSecretExtract struct {
// Key is the key used in the Provider
// +optional
Key string `json:"key,omitempty"`
// Used to select a specific version of the Provider value, if supported
// +optional
Version string `json:"version,omitempty"`
// +optional
// Used to select a specific property of the Provider value (if a map), if supported
Property string `json:"property,omitempty"`
}
type ExternalSecretFind struct {
// Key is the key used in the Provider
// +optional
Name FindName `json:"name,omitempty"`
// Used to select a specific version of the Provider value, if supported
// +optional
Tags map[string]string `json:"tags,omitempty"`
}
type FindName struct {
// Used to select multiple secrets based on a regular expression of the name
// +optional
RegExp string `json:"regexp,omitempty"`
}
// ExternalSecretSpec defines the desired state of ExternalSecret.
type ExternalSecretSpec struct {
SecretStoreRef SecretStoreRef `json:"secretStoreRef"`
@ -149,7 +197,7 @@ type ExternalSecretSpec struct {
// DataFrom is used to fetch all properties from a specific Provider data
// If multiple entries are specified, the Secret keys are merged in the specified order
// +optional
DataFrom []ExternalSecretDataRemoteRef `json:"dataFrom,omitempty"`
DataFrom []ExternalSecretDataFromRemoteRef `json:"dataFrom,omitempty"`
}
type ExternalSecretConditionType string

View file

@ -402,6 +402,23 @@ func (in *ExternalSecretData) DeepCopy() *ExternalSecretData {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalSecretDataFromRemoteRef) DeepCopyInto(out *ExternalSecretDataFromRemoteRef) {
*out = *in
out.Extract = in.Extract
in.Find.DeepCopyInto(&out.Find)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretDataFromRemoteRef.
func (in *ExternalSecretDataFromRemoteRef) DeepCopy() *ExternalSecretDataFromRemoteRef {
if in == nil {
return nil
}
out := new(ExternalSecretDataFromRemoteRef)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalSecretDataRemoteRef) DeepCopyInto(out *ExternalSecretDataRemoteRef) {
*out = *in
@ -417,6 +434,44 @@ func (in *ExternalSecretDataRemoteRef) DeepCopy() *ExternalSecretDataRemoteRef {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalSecretExtract) DeepCopyInto(out *ExternalSecretExtract) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretExtract.
func (in *ExternalSecretExtract) DeepCopy() *ExternalSecretExtract {
if in == nil {
return nil
}
out := new(ExternalSecretExtract)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalSecretFind) DeepCopyInto(out *ExternalSecretFind) {
*out = *in
out.Name = in.Name
if in.Tags != nil {
in, out := &in.Tags, &out.Tags
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretFind.
func (in *ExternalSecretFind) DeepCopy() *ExternalSecretFind {
if in == nil {
return nil
}
out := new(ExternalSecretFind)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalSecretList) DeepCopyInto(out *ExternalSecretList) {
*out = *in
@ -466,8 +521,10 @@ func (in *ExternalSecretSpec) DeepCopyInto(out *ExternalSecretSpec) {
}
if in.DataFrom != nil {
in, out := &in.DataFrom, &out.DataFrom
*out = make([]ExternalSecretDataRemoteRef, len(*in))
copy(*out, *in)
*out = make([]ExternalSecretDataFromRemoteRef, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
@ -599,6 +656,21 @@ func (in *ExternalSecretTemplateMetadata) DeepCopy() *ExternalSecretTemplateMeta
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FindName) DeepCopyInto(out *FindName) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FindName.
func (in *FindName) DeepCopy() *FindName {
if in == nil {
return nil
}
out := new(FindName)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GCPSMAuth) DeepCopyInto(out *GCPSMAuth) {
*out = *in

View file

@ -85,10 +85,15 @@ spec:
Provider data If multiple entries are specified, the Secret keys
are merged in the specified order
items:
description: ExternalSecretDataRemoteRef defines Provider data location.
description: ExternalSecretDataFromRemoteRef defines Provider data
location.
properties:
extract:
description: Used to select a specific version and property
from the secret
properties:
key:
description: Key is the key used in the Provider, mandatory
description: Key is the key used in the Provider
type: string
property:
description: Used to select a specific property of the Provider
@ -98,8 +103,25 @@ spec:
description: Used to select a specific version of the Provider
value, if supported
type: string
required:
- key
type: object
find:
description: Used to find secrets based on tags or regular expressions
properties:
name:
description: Key is the key used in the Provider
properties:
regexp:
description: Used to select multiple secrets based on
a regular expression of the name
type: string
type: object
tags:
additionalProperties:
type: string
description: Used to select a specific version of the Provider
value, if supported
type: object
type: object
type: object
type: array
refreshInterval:

View file

@ -4,6 +4,8 @@ be transformed and saved as a `Kind=Secret`:
* tells the operator what secrets should be synced by using `spec.data` to
explicitly sync individual keys or use `spec.dataFrom` to get **all values**
from the external API.
* you can also use `spec.dataFrom` to sync many secrets at once, based on a
regular expression of their name or on tags/attributes. You need to check if your provider implements this behavior or not.
* you can specify how the secret should look like by specifying a
`spec.target.template`

View file

@ -0,0 +1,70 @@
# Multiple secrets
In some escenarios, you may have different secrets in your Provider but you don't want to write an ExternalSecret for each of them. In that case, you can create a single ExternalSecret that will fetch many secrets and creates one single `Kind=Secret` with all of them.
Let's look an example on how to retrieve many different secrets.
In my Azure Key Vault I have all these secrets
![azure-key-vault](./pictures/screenshot_akv_secrets.png)
You cannot see it in the picture but using the Azure CLI tool aI can easily query them and display the name and tags, which is what I'm mostly interested in right now.
```sh
az keyvault secret list --vault-name=cs-akv-test-eso --query '[].{Name:name,Tags:tags}'
```
```json
[
{
"Name": "example-2",
"Tags": {}
},
{
"Name": "example-akv-externalsecret",
"Tags": {
"author": "seb",
"file-encoding": "utf-8"
}
},
{
"Name": "example-tagged",
"Tags": {
"author": "seb",
"environment": "dev"
}
},
{
"Name": "json-secret",
"Tags": {}
},
{
"Name": "tagged-secret",
"Tags": {
"author": "seb",
"environment": "dev"
}
}
]
```
### Creating dataFrom external secret
Now, when creating our ExternalSecret resource, instead of using the data field, we use the dataFrom field:
```yaml
{% include 'akv-data-from-external-secret.yaml' %}
```
To check both values we can run:
```sh
kubectl get secret secret-to-be-created -o jsonpath='{.data}'
```
```json
{
"example-2": "VGhpcyBpcyBhbm90aGVyIHNlY3JldA==",
"example-akv-externalsecret": "VGhpcyBpcyBhIHZlcnkgc2VjdXJlIHNlY3JldA==",
"example-tagged": "VGhpcyBpcyB0aGUgdGFnZ2VkIGV4YW1wbGU=",
"tagged-secret": "VGhpcyBpcyBhIHRhZ2dlZCBzZWNyZXQ="
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

View file

@ -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

View file

@ -0,0 +1,20 @@
apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
metadata:
name: example
spec:
refreshInterval: 1h # rate SecretManager pulls Azure Key Vault
secretStoreRef:
kind: SecretStore
name: example # name of the SecretStore (or kind specified)
target:
name: secret-to-be-created # name of the k8s Secret to be created
creationPolicy: Owner
dataFrom:
- find:
name:
regexp: "^example"
- find:
tags:
author: seb
environment: dev

View file

@ -38,4 +38,6 @@ spec:
# dataFrom , return ALL secrets saved in the referenced secretStore
# each secret name in the KV will be used as the secret key in the SECRET k8s target object
dataFrom:
- name: "*"
- find:
name:
regexp: "regexp-name"

View file

@ -17,4 +17,5 @@ spec:
version: provider-key-version
property: provider-key-property
dataFrom:
- key: remote-key-in-the-provider
- extract:
key: provider-key

View file

@ -70,12 +70,19 @@ spec:
version: provider-key-version
property: provider-key-property
# Used to fetch all properties from the Provider key
# Used to fetch the desired property from the Provider key
# If multiple dataFrom are specified, secrets are merged in the specified order
dataFrom:
- key: provider-key
- extract: # Supported methods are `extract` and `find`. If both are defined, `extract` is ignored.
key: provider-key
version: provider-key-version
property: provider-key-property
- find: # Used to fetch many secrets based on a regular expression of their name
name:
regexp: "regexp-name"
- find: # Used to fetch many secrets based on the tags (or attributes) in the Provider
tags:
tag-key: tag-value
status:
# refreshTime is the time and date the external secret was fetched and

View file

@ -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

View file

@ -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: all-keys-example-secret # Key of the variable on Gitlab

View file

@ -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

View file

@ -908,8 +908,8 @@ May be set to zero to fetch and create it once. Defaults to 1h.</p>
<td>
<code>dataFrom</code></br>
<em>
<a href="#external-secrets.io/v1alpha1.ExternalSecretDataRemoteRef">
[]ExternalSecretDataRemoteRef
<a href="#external-secrets.io/v1alpha1.ExternalSecretDataFromRemoteRef">
[]ExternalSecretDataFromRemoteRef
</a>
</em>
</td>
@ -1025,12 +1025,58 @@ ExternalSecretDataRemoteRef
</tr>
</tbody>
</table>
<h3 id="external-secrets.io/v1alpha1.ExternalSecretDataFromRemoteRef">ExternalSecretDataFromRemoteRef
</h3>
<p>
(<em>Appears on:</em>
<a href="#external-secrets.io/v1alpha1.ExternalSecretSpec">ExternalSecretSpec</a>)
</p>
<p>
<p>ExternalSecretDataFromRemoteRef defines Provider data location.</p>
</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>extract</code></br>
<em>
<a href="#external-secrets.io/v1alpha1.ExternalSecretExtract">
ExternalSecretExtract
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Used to select a specific version and property from the secret</p>
</td>
</tr>
<tr>
<td>
<code>find</code></br>
<em>
<a href="#external-secrets.io/v1alpha1.ExternalSecretFind">
ExternalSecretFind
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Used to find secrets based on tags or regular expressions</p>
</td>
</tr>
</tbody>
</table>
<h3 id="external-secrets.io/v1alpha1.ExternalSecretDataRemoteRef">ExternalSecretDataRemoteRef
</h3>
<p>
(<em>Appears on:</em>
<a href="#external-secrets.io/v1alpha1.ExternalSecretData">ExternalSecretData</a>,
<a href="#external-secrets.io/v1alpha1.ExternalSecretSpec">ExternalSecretSpec</a>)
<a href="#external-secrets.io/v1alpha1.ExternalSecretData">ExternalSecretData</a>)
</p>
<p>
<p>ExternalSecretDataRemoteRef defines Provider data location.</p>
@ -1080,6 +1126,104 @@ string
</tr>
</tbody>
</table>
<h3 id="external-secrets.io/v1alpha1.ExternalSecretExtract">ExternalSecretExtract
</h3>
<p>
(<em>Appears on:</em>
<a href="#external-secrets.io/v1alpha1.ExternalSecretDataFromRemoteRef">ExternalSecretDataFromRemoteRef</a>)
</p>
<p>
</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>key</code></br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Key is the key used in the Provider</p>
</td>
</tr>
<tr>
<td>
<code>version</code></br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Used to select a specific version of the Provider value, if supported</p>
</td>
</tr>
<tr>
<td>
<code>property</code></br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Used to select a specific property of the Provider value (if a map), if supported</p>
</td>
</tr>
</tbody>
</table>
<h3 id="external-secrets.io/v1alpha1.ExternalSecretFind">ExternalSecretFind
</h3>
<p>
(<em>Appears on:</em>
<a href="#external-secrets.io/v1alpha1.ExternalSecretDataFromRemoteRef">ExternalSecretDataFromRemoteRef</a>)
</p>
<p>
</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>name</code></br>
<em>
<a href="#external-secrets.io/v1alpha1.FindName">
FindName
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Key is the key used in the Provider</p>
</td>
</tr>
<tr>
<td>
<code>tags</code></br>
<em>
map[string]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Used to select a specific version of the Provider value, if supported</p>
</td>
</tr>
</tbody>
</table>
<h3 id="external-secrets.io/v1alpha1.ExternalSecretSpec">ExternalSecretSpec
</h3>
<p>
@ -1154,8 +1298,8 @@ May be set to zero to fetch and create it once. Defaults to 1h.</p>
<td>
<code>dataFrom</code></br>
<em>
<a href="#external-secrets.io/v1alpha1.ExternalSecretDataRemoteRef">
[]ExternalSecretDataRemoteRef
<a href="#external-secrets.io/v1alpha1.ExternalSecretDataFromRemoteRef">
[]ExternalSecretDataFromRemoteRef
</a>
</em>
</td>
@ -1486,6 +1630,36 @@ map[string]string
</tr>
</tbody>
</table>
<h3 id="external-secrets.io/v1alpha1.FindName">FindName
</h3>
<p>
(<em>Appears on:</em>
<a href="#external-secrets.io/v1alpha1.ExternalSecretFind">ExternalSecretFind</a>)
</p>
<p>
</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>regexp</code></br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Used to select multiple secrets based on a regular expression of the name</p>
</td>
</tr>
</tbody>
</table>
<h3 id="external-secrets.io/v1alpha1.GCPSMAuth">GCPSMAuth
</h3>
<p>

View file

@ -235,10 +235,12 @@ func JSONDataFromSync(f *framework.Framework) (string, func(*framework.TestCase)
targetSecretKey2: []byte(targetSecretValue2),
},
}
tc.ExternalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
tc.ExternalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataFromRemoteRef{
{
Extract: esv1alpha1.ExternalSecretExtract{
Key: secretKey1,
},
},
}
}
}

View file

@ -32,6 +32,7 @@ nav:
- Getting started: guides-getting-started.md
- Advanced Templating: guides-templating.md
- All keys, One secret: guides-all-keys-one-secret.md
- Multiple secrets: guides-multiple-secrets.md
- Common K8S Secret Types: guides-common-k8s-secret-types.md
- Multi Tenancy: guides-multi-tenancy.md
- Metrics: guides-metrics.md

View file

@ -397,11 +397,22 @@ func (r *Reconciler) getProviderSecretData(ctx context.Context, providerClient p
providerData := make(map[string][]byte)
for _, remoteRef := range externalSecret.Spec.DataFrom {
secretMap, err := providerClient.GetSecretMap(ctx, remoteRef)
if err != nil {
return nil, fmt.Errorf(errGetSecretKey, remoteRef.Key, externalSecret.Name, err)
}
var secretMap map[string][]byte
var err error
// If tags were added get all secret by tags
// Also if a regular expression was entered
if len(remoteRef.Find.Tags) > 0 || len(remoteRef.Find.Name.RegExp) > 0 {
secretMap, err = providerClient.GetAllSecrets(ctx, remoteRef)
if err != nil {
return nil, fmt.Errorf(errGetSecretKey, remoteRef.Extract.Key, externalSecret.Name, err)
}
} else {
secretMap, err = providerClient.GetSecretMap(ctx, remoteRef)
if err != nil {
return nil, fmt.Errorf(errGetSecretKey, remoteRef.Extract.Key, externalSecret.Name, err)
}
}
providerData = utils.MergeByteMap(providerData, secretMap)
}

View file

@ -138,6 +138,8 @@ var _ = Describe("ExternalSecret controller", func() {
targetPropObj = "{{ .targetProperty | toString | upper }} was templated"
FooValue = "map-foo-value"
BarValue = "map-bar-value"
foo = "foo"
bar = "bar"
)
var ExternalSecretNamespace string
@ -520,21 +522,23 @@ var _ = Describe("ExternalSecret controller", func() {
tplStaticKey: tplStaticVal,
},
}
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataFromRemoteRef{
{
Extract: esv1alpha1.ExternalSecretExtract{
Key: "datamap",
},
},
}
fakeProvider.WithGetSecret([]byte(secretVal), nil)
fakeProvider.WithGetSecretMap(map[string][]byte{
"targetProperty": []byte(FooValue),
"bar": []byte(BarValue),
bar: []byte(BarValue),
}, nil)
tc.checkSecret = func(es *esv1alpha1.ExternalSecret, secret *v1.Secret) {
// check values
Expect(string(secret.Data[targetProp])).To(Equal(expectedSecretVal))
Expect(string(secret.Data[tplStaticKey])).To(Equal(tplStaticVal))
Expect(string(secret.Data["bar"])).To(Equal("value from map: map-bar-value"))
Expect(string(secret.Data[bar])).To(Equal("value from map: map-bar-value"))
Expect(string(secret.Data[tplFromKey])).To(Equal("tpl-from-value: someValue // map-bar-value"))
Expect(string(secret.Data[tplFromSecKey])).To(Equal("tpl-from-sec-value: someValue // map-bar-value"))
}
@ -547,8 +551,8 @@ var _ = Describe("ExternalSecret controller", func() {
tc.externalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second}
tc.externalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
Metadata: esv1alpha1.ExternalSecretTemplateMetadata{
Labels: map[string]string{"foo": "bar"},
Annotations: map[string]string{"foo": "bar"},
Labels: map[string]string{foo: bar},
Annotations: map[string]string{foo: bar},
},
Type: v1.SecretTypeOpaque,
Data: map[string]string{
@ -607,8 +611,8 @@ var _ = Describe("ExternalSecret controller", func() {
tc.externalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second}
tc.externalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{
Metadata: esv1alpha1.ExternalSecretTemplateMetadata{
Labels: map[string]string{"foo": "bar"},
Annotations: map[string]string{"foo": "bar"},
Labels: map[string]string{foo: bar},
Annotations: map[string]string{foo: bar},
},
}
fakeProvider.WithGetSecret([]byte(secretVal), nil)
@ -662,10 +666,12 @@ var _ = Describe("ExternalSecret controller", func() {
"bar": []byte("2222"),
}, nil)
tc.externalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{}
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataFromRemoteRef{
{
Extract: esv1alpha1.ExternalSecretExtract{
Key: remoteKey,
},
},
}
tc.externalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second}
tc.checkSecret = func(es *esv1alpha1.ExternalSecret, secret *v1.Secret) {
@ -702,10 +708,12 @@ var _ = Describe("ExternalSecret controller", func() {
}, nil)
tc.externalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{}
tc.externalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{}
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataFromRemoteRef{
{
Extract: esv1alpha1.ExternalSecretExtract{
Key: remoteKey,
},
},
}
tc.externalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second}
tc.checkSecret = func(es *esv1alpha1.ExternalSecret, secret *v1.Secret) {
@ -765,19 +773,21 @@ var _ = Describe("ExternalSecret controller", func() {
// should be put into the secret
syncWithDataFrom := func(tc *testCase) {
tc.externalSecret.Spec.Data = nil
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataFromRemoteRef{
{
Extract: esv1alpha1.ExternalSecretExtract{
Key: remoteKey,
},
},
}
fakeProvider.WithGetSecretMap(map[string][]byte{
"foo": []byte(FooValue),
"bar": []byte(BarValue),
foo: []byte(FooValue),
bar: []byte(BarValue),
}, nil)
tc.checkSecret = func(es *esv1alpha1.ExternalSecret, secret *v1.Secret) {
// check values
Expect(string(secret.Data["foo"])).To(Equal(FooValue))
Expect(string(secret.Data["bar"])).To(Equal(BarValue))
Expect(string(secret.Data[foo])).To(Equal(FooValue))
Expect(string(secret.Data[bar])).To(Equal(BarValue))
}
}
@ -792,10 +802,12 @@ var _ = Describe("ExternalSecret controller", func() {
},
}
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataFromRemoteRef{
{
Extract: esv1alpha1.ExternalSecretExtract{
Key: remoteKey,
},
},
}
fakeProvider.WithGetSecretMap(map[string][]byte{
"tls.crt": []byte(FooValue),
@ -812,7 +824,7 @@ var _ = Describe("ExternalSecret controller", func() {
// when a provider errors in a GetSecret call
// a error condition must be set.
providerErrCondition := func(tc *testCase) {
const secretVal = "foobar"
const secretVal = foo + bar
fakeProvider.WithGetSecret(nil, fmt.Errorf("boom"))
tc.externalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Millisecond * 100}
tc.checkCondition = func(es *esv1alpha1.ExternalSecret) bool {

View file

@ -128,14 +128,21 @@ func (a *Akeyless) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretD
return []byte(value), nil
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (a *Akeyless) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
// Implements store.Client.GetSecretMap Interface.
// New version of GetSecretMap.
func (a *Akeyless) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
func (a *Akeyless) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
if utils.IsNil(a.Client) {
return nil, fmt.Errorf(errUninitalizedAkeylessProvider)
}
val, err := a.GetSecret(ctx, ref)
val, err := a.GetSecret(ctx, ref.GetDataRemoteRef())
if err != nil {
return nil, err
}

View file

@ -22,6 +22,7 @@ import (
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
fakeakeyless "github.com/external-secrets/external-secrets/pkg/provider/akeyless/fake"
"github.com/external-secrets/external-secrets/pkg/utils"
)
type akeylessTestCase struct {
@ -29,6 +30,7 @@ type akeylessTestCase struct {
apiInput *fakeakeyless.Input
apiOutput *fakeakeyless.Output
ref *esv1alpha1.ExternalSecretDataRemoteRef
refFrom *esv1alpha1.ExternalSecretDataFromRemoteRef
expectError string
expectedSecret string
// for testing secretmap
@ -39,7 +41,8 @@ func makeValidAkeylessTestCase() *akeylessTestCase {
smtc := akeylessTestCase{
mockClient: &fakeakeyless.AkeylessMockClient{},
apiInput: makeValidInput(),
ref: makeValidRef(),
ref: utils.MakeValidRef(),
refFrom: utils.MakeValidRefFrom(),
apiOutput: makeValidOutput(),
expectError: "",
expectedSecret: "",
@ -49,13 +52,6 @@ func makeValidAkeylessTestCase() *akeylessTestCase {
return &smtc
}
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
return &esv1alpha1.ExternalSecretDataRemoteRef{
Key: "test-secret",
Version: "1",
}
}
func makeValidInput() *fakeakeyless.Input {
return &fakeakeyless.Input{
SecretName: "name",
@ -147,7 +143,7 @@ func TestGetSecretMap(t *testing.T) {
sm := Akeyless{}
for k, v := range successCases {
sm.Client = v.mockClient
out, err := sm.GetSecretMap(context.Background(), *v.ref)
out, err := sm.GetSecretMap(context.Background(), *v.refFrom)
if !ErrorContains(err, v.expectError) {
t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
}

View file

@ -140,16 +140,23 @@ func (kms *KeyManagementService) GetSecret(ctx context.Context, ref esv1alpha1.E
return []byte(val.String()), nil
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (kms *KeyManagementService) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
// GetSecretMap returns multiple k/v pairs from the provider.
func (kms *KeyManagementService) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
data, err := kms.GetSecret(ctx, ref)
func (kms *KeyManagementService) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
data, err := kms.GetSecret(ctx, ref.GetDataRemoteRef())
if err != nil {
return nil, err
}
kv := make(map[string]string)
err = json.Unmarshal(data, &kv)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Key, err)
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Extract.Key, err)
}
secretData := make(map[string][]byte)
for k, v := range kv {

View file

@ -26,6 +26,7 @@ import (
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
fakesm "github.com/external-secrets/external-secrets/pkg/provider/alibaba/fake"
"github.com/external-secrets/external-secrets/pkg/utils"
)
const (
@ -38,6 +39,7 @@ type keyManagementServiceTestCase struct {
apiInput *kmssdk.GetSecretValueRequest
apiOutput *kmssdk.GetSecretValueResponse
ref *esv1alpha1.ExternalSecretDataRemoteRef
refFrom *esv1alpha1.ExternalSecretDataFromRemoteRef
apiErr error
expectError string
expectedSecret string
@ -49,7 +51,8 @@ func makeValidKMSTestCase() *keyManagementServiceTestCase {
kmstc := keyManagementServiceTestCase{
mockClient: &fakesm.AlibabaMockClient{},
apiInput: makeValidAPIInput(),
ref: makeValidRef(),
ref: utils.MakeValidRef(),
refFrom: utils.MakeValidRefFrom(),
apiOutput: makeValidAPIOutput(),
apiErr: nil,
expectError: "",
@ -60,12 +63,6 @@ func makeValidKMSTestCase() *keyManagementServiceTestCase {
return &kmstc
}
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
return &esv1alpha1.ExternalSecretDataRemoteRef{
Key: secretName,
}
}
func makeValidAPIInput() *kmssdk.GetSecretValueRequest {
return &kmssdk.GetSecretValueRequest{
SecretName: secretName,
@ -176,7 +173,7 @@ func TestGetSecretMap(t *testing.T) {
sm := KeyManagementService{}
for k, v := range successCases {
sm.Client = v.mockClient
out, err := sm.GetSecretMap(context.Background(), *v.ref)
out, err := sm.GetSecretMap(context.Background(), *v.refFrom)
if !ErrorContains(err, v.expectError) {
t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
}

View file

@ -26,6 +26,7 @@ import (
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
"github.com/external-secrets/external-secrets/pkg/provider/aws/util"
"github.com/external-secrets/external-secrets/pkg/utils"
)
// ParameterStore is a provider for AWS ParameterStore.
@ -71,17 +72,24 @@ func (pm *ParameterStore) GetSecret(ctx context.Context, ref esv1alpha1.External
return []byte(val.String()), nil
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (pm *ParameterStore) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
// GetSecretMap returns multiple k/v pairs from the provider.
func (pm *ParameterStore) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
log.Info("fetching secret map", "key", ref.Key)
data, err := pm.GetSecret(ctx, ref)
func (pm *ParameterStore) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
log.Info("fetching secret map", "key", ref.Extract.Key)
data, err := pm.GetSecret(ctx, ref.GetDataRemoteRef())
if err != nil {
return nil, err
}
kv := make(map[string]string)
err = json.Unmarshal(data, &kv)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Key, err)
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Extract.Key, err)
}
secretData := make(map[string][]byte)
for k, v := range kv {

View file

@ -32,6 +32,7 @@ type parameterstoreTestCase struct {
apiInput *ssm.GetParameterInput
apiOutput *ssm.GetParameterOutput
remoteRef *esv1alpha1.ExternalSecretDataRemoteRef
remoteRefFrom *esv1alpha1.ExternalSecretDataFromRemoteRef
apiErr error
expectError string
expectedSecret string
@ -44,6 +45,7 @@ func makeValidParameterStoreTestCase() *parameterstoreTestCase {
apiInput: makeValidAPIInput(),
apiOutput: makeValidAPIOutput(),
remoteRef: makeValidRemoteRef(),
remoteRefFrom: makeValidRemoteRefFrom(),
apiErr: nil,
expectError: "",
expectedSecret: "",
@ -72,6 +74,14 @@ func makeValidRemoteRef() *esv1alpha1.ExternalSecretDataRemoteRef {
}
}
func makeValidRemoteRefFrom() *esv1alpha1.ExternalSecretDataFromRemoteRef {
return &esv1alpha1.ExternalSecretDataFromRemoteRef{
Extract: esv1alpha1.ExternalSecretExtract{
Key: "/baz",
},
}
}
func makeValidParameterStoreTestCaseCustom(tweaks ...func(pstc *parameterstoreTestCase)) *parameterstoreTestCase {
pstc := makeValidParameterStoreTestCase()
for _, fn := range tweaks {
@ -174,7 +184,7 @@ func TestGetSecretMap(t *testing.T) {
ps := ParameterStore{}
for k, v := range successCases {
ps.client = v.fakeClient
out, err := ps.GetSecretMap(context.Background(), *v.remoteRef)
out, err := ps.GetSecretMap(context.Background(), *v.remoteRefFrom)
if !ErrorContains(err, v.expectError) {
t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
}

View file

@ -26,6 +26,7 @@ import (
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
"github.com/external-secrets/external-secrets/pkg/provider/aws/util"
"github.com/external-secrets/external-secrets/pkg/utils"
)
// SecretsManager is a provider for AWS SecretsManager.
@ -105,16 +106,16 @@ func (sm *SecretsManager) GetSecret(ctx context.Context, ref esv1alpha1.External
}
// GetSecretMap returns multiple k/v pairs from the provider.
func (sm *SecretsManager) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
log.Info("fetching secret map", "key", ref.Key)
data, err := sm.GetSecret(ctx, ref)
func (sm *SecretsManager) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
log.Info("fetching secret map", "key", ref.Extract.Key)
data, err := sm.GetSecret(ctx, ref.GetDataRemoteRef())
if err != nil {
return nil, err
}
kv := make(map[string]json.RawMessage)
err = json.Unmarshal(data, &kv)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Key, err)
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Extract.Key, err)
}
secretData := make(map[string][]byte)
for k, v := range kv {
@ -129,6 +130,13 @@ func (sm *SecretsManager) GetSecretMap(ctx context.Context, ref esv1alpha1.Exter
return secretData, nil
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (sm *SecretsManager) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
func (sm *SecretsManager) Close(ctx context.Context) error {
return nil
}

View file

@ -33,6 +33,7 @@ type secretsManagerTestCase struct {
apiInput *awssm.GetSecretValueInput
apiOutput *awssm.GetSecretValueOutput
remoteRef *esv1alpha1.ExternalSecretDataRemoteRef
remoteRefFrom *esv1alpha1.ExternalSecretDataFromRemoteRef
apiErr error
expectError string
expectedSecret string
@ -49,6 +50,7 @@ func makeValidSecretsManagerTestCase() *secretsManagerTestCase {
fakeClient: fakesm.NewClient(),
apiInput: makeValidAPIInput(),
remoteRef: makeValidRemoteRef(),
remoteRefFrom: makeValidRemoteRefFrom(),
apiOutput: makeValidAPIOutput(),
apiErr: nil,
expectError: "",
@ -66,6 +68,15 @@ func makeValidRemoteRef() *esv1alpha1.ExternalSecretDataRemoteRef {
}
}
func makeValidRemoteRefFrom() *esv1alpha1.ExternalSecretDataFromRemoteRef {
return &esv1alpha1.ExternalSecretDataFromRemoteRef{
Extract: esv1alpha1.ExternalSecretExtract{
Key: "/baz",
Version: "AWSCURRENT",
},
}
}
func makeValidAPIInput() *awssm.GetSecretValueInput {
return &awssm.GetSecretValueInput{
SecretId: aws.String("/baz"),
@ -276,7 +287,7 @@ func TestGetSecretMap(t *testing.T) {
cache: make(map[string]*awssm.GetSecretValueOutput),
client: v.fakeClient,
}
out, err := sm.GetSecretMap(context.Background(), *v.remoteRef)
out, err := sm.GetSecretMap(context.Background(), *v.remoteRefFrom)
if !ErrorContains(err, v.expectError) {
t.Errorf(unexpectedErrorString, k, err.Error(), v.expectError)
}

View file

@ -65,3 +65,11 @@ func (mc *AzureMockClient) WithCertificate(serviceURL, secretName, secretVersion
}
}
}
func (mc *AzureMockClient) WithList(serviceURL string, apiOutput keyvault.SecretListResultIterator, err error) {
if mc != nil {
mc.getSecretsComplete = func(ctx context.Context, vaultBaseURL string, maxresults *int32) (result keyvault.SecretListResultIterator, err error) {
return apiOutput, err
}
}
}

View file

@ -18,6 +18,8 @@ import (
"context"
"encoding/json"
"fmt"
"path"
"regexp"
"strings"
"github.com/Azure/azure-sdk-for-go/profiles/latest/keyvault/keyvault"
@ -93,6 +95,10 @@ func (a *Azure) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretData
basicClient := a.baseClient
objectType, secretName := getObjType(ref)
if secretName == "" {
return nil, fmt.Errorf("%s name cannot be empty", objectType)
}
if ref.Version != "" {
version = ref.Version
}
@ -137,12 +143,13 @@ func (a *Azure) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretData
// Implements store.Client.GetSecretMap Interface.
// New version of GetSecretMap.
func (a *Azure) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
objectType, secretName := getObjType(ref)
func (a *Azure) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
dataRef := ref.GetDataRemoteRef()
objectType, secretName := getObjType(dataRef)
switch objectType {
case defaultObjType:
data, err := a.GetSecret(ctx, ref)
data, err := a.GetSecret(ctx, dataRef)
if err != nil {
return nil, err
}
@ -168,6 +175,76 @@ func (a *Azure) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretD
return nil, fmt.Errorf("unknown Azure Keyvault object Type for %s", secretName)
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (a *Azure) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
basicClient := a.baseClient
secretsMap := make(map[string][]byte)
checkTags := len(ref.Find.Tags) > 0
checkName := len(ref.Find.Name.RegExp) > 0
secretListIter, err := basicClient.GetSecretsComplete(context.Background(), a.vaultURL, nil)
if err != nil {
return nil, err
}
for secretListIter.NotDone() {
secretList := secretListIter.Response().Value
for _, secret := range *secretList {
ok, secretName := isValidSecret(checkTags, checkName, ref, secret)
if !ok {
continue
}
secretResp, err := basicClient.GetSecret(context.Background(), a.vaultURL, secretName, "")
secretValue := *secretResp.Value
if err != nil {
return nil, err
}
secretsMap[secretName] = []byte(secretValue)
}
err = secretListIter.Next()
if err != nil {
return nil, err
}
}
return secretsMap, nil
}
func isValidSecret(checkTags, checkName bool, ref esv1alpha1.ExternalSecretDataFromRemoteRef, secret keyvault.SecretItem) (bool, string) {
if secret.ID == nil || !*secret.Attributes.Enabled {
return false, ""
}
if checkTags && !okByTags(ref, secret) {
return false, ""
}
secretName := path.Base(*secret.ID)
if checkName && !okByName(ref, secretName) {
return false, ""
}
return true, secretName
}
func okByName(ref esv1alpha1.ExternalSecretDataFromRemoteRef, secretName string) bool {
matches, _ := regexp.MatchString(ref.Find.Name.RegExp, secretName)
return matches
}
func okByTags(ref esv1alpha1.ExternalSecretDataFromRemoteRef, secret keyvault.SecretItem) bool {
tagsFound := true
for k, v := range ref.Find.Tags {
if val, ok := secret.Tags[k]; !ok || *val != v {
tagsFound = false
break
}
}
return tagsFound
}
func (a *Azure) setAzureClientWithManagedIdentity() (bool, error) {
spec := *a.store.GetSpec().Provider.AzureKV

View file

@ -30,7 +30,7 @@ import (
v1 "github.com/external-secrets/external-secrets/apis/meta/v1"
fake "github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault/fake"
"github.com/external-secrets/external-secrets/pkg/provider/schema"
utils "github.com/external-secrets/external-secrets/pkg/utils"
"github.com/external-secrets/external-secrets/pkg/utils"
)
type secretManagerTestCase struct {
@ -39,10 +39,12 @@ type secretManagerTestCase struct {
secretVersion string
serviceURL string
ref *esv1alpha1.ExternalSecretDataRemoteRef
refFrom *esv1alpha1.ExternalSecretDataFromRemoteRef
apiErr error
secretOutput keyvault.SecretBundle
keyOutput keyvault.KeyBundle
certOutput keyvault.CertificateBundle
listOutput keyvault.SecretListResultIterator
expectError string
expectedSecret string
// for testing secretmap
@ -55,7 +57,8 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
mockClient: &fake.AzureMockClient{},
secretName: "MySecret",
secretVersion: "",
ref: makeValidRef(),
ref: utils.MakeValidRef(),
refFrom: utils.MakeValidRefFrom(),
secretOutput: keyvault.SecretBundle{Value: &secretString},
serviceURL: "",
apiErr: nil,
@ -78,6 +81,7 @@ func makeValidSecretManagerTestCaseCustom(tweaks ...func(smtc *secretManagerTest
smtc.mockClient.WithValue(smtc.serviceURL, smtc.secretName, smtc.secretVersion, smtc.secretOutput, smtc.apiErr)
smtc.mockClient.WithKey(smtc.serviceURL, smtc.secretName, smtc.secretVersion, smtc.keyOutput, smtc.apiErr)
smtc.mockClient.WithCertificate(smtc.serviceURL, smtc.secretName, smtc.secretVersion, smtc.certOutput, smtc.apiErr)
smtc.mockClient.WithList(smtc.serviceURL, smtc.listOutput, smtc.apiErr)
return smtc
}
@ -159,6 +163,11 @@ const (
jsonSingleTestString = `{"Name": "External", "LastName": "Secret" }`
keyName = "key/keyname"
certName = "cert/certname"
secretString = "changedvalue"
unexpectedError = "[%d] unexpected error: %s, expected: '%s'"
unexpectedSecret = "[%d] unexpected secret: expected %s, got %s"
unexpectedSecretData = "[%d] unexpected secret data: expected %#v, got %#v"
secretName = "example-1"
)
func newKVJWK(b []byte) *keyvault.JSONWebKey {
@ -173,7 +182,7 @@ func newKVJWK(b []byte) *keyvault.JSONWebKey {
// test the sm<->azurekv interface
// make sure correct values are passed and errors are handled accordingly.
func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
secretString := "changedvalue"
secretString := secretString
secretCertificate := "certificate_value"
// good case
@ -184,6 +193,13 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
}
}
badNoNameSecret := func(smtc *secretManagerTestCase) {
smtc.ref.Key = ""
smtc.expectedSecret = ""
smtc.secretName = "secret/"
smtc.expectError = fmt.Sprintf("%s name cannot be empty", "secret")
}
setSecretStringWithVersion := func(smtc *secretManagerTestCase) {
smtc.expectedSecret = secretString
smtc.secretOutput = keyvault.SecretBundle{
@ -254,6 +270,7 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
successCases := []*secretManagerTestCase{
makeValidSecretManagerTestCase(),
makeValidSecretManagerTestCaseCustom(setSecretString),
makeValidSecretManagerTestCaseCustom(badNoNameSecret),
makeValidSecretManagerTestCaseCustom(setSecretStringWithVersion),
makeValidSecretManagerTestCaseCustom(setSecretWithProperty),
makeValidSecretManagerTestCaseCustom(badSecretWithProperty),
@ -268,16 +285,16 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
sm.baseClient = v.mockClient
out, err := sm.GetSecret(context.Background(), *v.ref)
if !utils.ErrorContains(err, v.expectError) {
t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
t.Errorf(unexpectedError, k, err.Error(), v.expectError)
}
if string(out) != v.expectedSecret {
t.Errorf("[%d] unexpected secret: expected %s, got %s", k, v.expectedSecret, string(out))
t.Errorf(unexpectedSecret, k, v.expectedSecret, string(out))
}
}
}
func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
secretString := "changedvalue"
secretString := secretString
secretCertificate := "certificate_value"
badSecretString := func(smtc *secretManagerTestCase) {
@ -302,7 +319,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
smtc.secretOutput = keyvault.SecretBundle{
Value: &jsonString,
}
smtc.ref.Property = "Address"
smtc.refFrom.Extract.Property = "Address"
smtc.expectedData["Street"] = []byte("Myroad st.")
smtc.expectedData["CP"] = []byte("J4K4T4")
@ -314,7 +331,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
smtc.secretOutput = keyvault.SecretBundle{
Value: &jsonString,
}
smtc.ref.Property = "Age"
smtc.refFrom.Extract.Property = "Age"
smtc.expectError = fmt.Sprintf("property %s does not exist in key %s", smtc.ref.Property, smtc.ref.Key)
smtc.apiErr = fmt.Errorf(smtc.expectError)
}
@ -325,7 +342,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
smtc.keyOutput = keyvault.KeyBundle{
Key: newKVJWK([]byte(jwkPubRSA)),
}
smtc.ref.Key = smtc.secretName
smtc.refFrom.Extract.Key = smtc.secretName
smtc.expectError = "cannot get use dataFrom to get key secret"
}
@ -336,7 +353,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
smtc.certOutput = keyvault.CertificateBundle{
Cer: &byteArrString,
}
smtc.ref.Key = smtc.secretName
smtc.refFrom.Extract.Key = smtc.secretName
smtc.expectError = "cannot get use dataFrom to get certificate secret"
}
@ -344,7 +361,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
smtc.secretName = "name"
smtc.expectedSecret = ""
smtc.expectError = fmt.Sprintf("unknown Azure Keyvault object Type for %s", smtc.secretName)
smtc.ref.Key = fmt.Sprintf("dummy/%s", smtc.secretName)
smtc.refFrom.Extract.Key = fmt.Sprintf("dummy/%s", smtc.secretName)
}
successCases := []*secretManagerTestCase{
@ -360,19 +377,168 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
sm := Azure{}
for k, v := range successCases {
sm.baseClient = v.mockClient
out, err := sm.GetSecretMap(context.Background(), *v.ref)
out, err := sm.GetSecretMap(context.Background(), *v.refFrom)
if !utils.ErrorContains(err, v.expectError) {
t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
t.Errorf(unexpectedError, k, err.Error(), v.expectError)
}
if err == nil && !reflect.DeepEqual(out, v.expectedData) {
t.Errorf("[%d] unexpected secret data: expected %#v, got %#v", k, v.expectedData, out)
t.Errorf(unexpectedSecretData, k, v.expectedData, out)
}
}
}
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
return &esv1alpha1.ExternalSecretDataRemoteRef{
Key: "test-secret",
Version: "default",
func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
secretString := secretString
secretName := secretName
wrongName := "not-valid"
environment := "dev"
author := "seb"
regexp := "^example"
enabled := true
getNextPage := func(ctx context.Context, list keyvault.SecretListResult) (result keyvault.SecretListResult, err error) {
return keyvault.SecretListResult{
Value: nil,
NextLink: nil,
}, nil
}
setOneSecretByName := func(smtc *secretManagerTestCase) {
smtc.refFrom.Find.Name.RegExp = regexp
enabledAtt := keyvault.SecretAttributes{
Enabled: &enabled,
}
secretItem := keyvault.SecretItem{
ID: &secretName,
Attributes: &enabledAtt,
}
secretList := make([]keyvault.SecretItem, 0)
secretList = append(secretList, secretItem)
list := keyvault.SecretListResult{
Value: &secretList,
}
resultPage := keyvault.NewSecretListResultPage(list, getNextPage)
smtc.listOutput = keyvault.NewSecretListResultIterator(resultPage)
smtc.expectedSecret = secretString
smtc.secretOutput = keyvault.SecretBundle{
Value: &secretString,
}
smtc.expectedData[secretName] = []byte(secretString)
}
setTwoSecretsByName := func(smtc *secretManagerTestCase) {
smtc.refFrom.Find.Name.RegExp = regexp
enabledAtt := keyvault.SecretAttributes{
Enabled: &enabled,
}
secretItemOne := keyvault.SecretItem{
ID: &secretName,
Attributes: &enabledAtt,
}
secretItemTwo := keyvault.SecretItem{
ID: &wrongName,
Attributes: &enabledAtt,
}
secretList := make([]keyvault.SecretItem, 1)
secretList = append(secretList, secretItemOne, secretItemTwo)
list := keyvault.SecretListResult{
Value: &secretList,
}
resultPage := keyvault.NewSecretListResultPage(list, getNextPage)
smtc.listOutput = keyvault.NewSecretListResultIterator(resultPage)
smtc.expectedSecret = secretString
smtc.secretOutput = keyvault.SecretBundle{
Value: &secretString,
}
smtc.expectedData[secretName] = []byte(secretString)
}
setOneSecretByTag := func(smtc *secretManagerTestCase) {
enabledAtt := keyvault.SecretAttributes{
Enabled: &enabled,
}
secretItem := keyvault.SecretItem{
ID: &secretName,
Attributes: &enabledAtt,
Tags: map[string]*string{"environment": &environment},
}
secretList := make([]keyvault.SecretItem, 0)
secretList = append(secretList, secretItem)
list := keyvault.SecretListResult{
Value: &secretList,
}
resultPage := keyvault.NewSecretListResultPage(list, getNextPage)
smtc.listOutput = keyvault.NewSecretListResultIterator(resultPage)
smtc.expectedSecret = secretString
smtc.secretOutput = keyvault.SecretBundle{
Value: &secretString,
}
smtc.refFrom.Find.Tags = map[string]string{"environment": environment}
smtc.expectedData[secretName] = []byte(secretString)
}
setTwoSecretsByTag := func(smtc *secretManagerTestCase) {
enabled := true
enabledAtt := keyvault.SecretAttributes{
Enabled: &enabled,
}
secretItem := keyvault.SecretItem{
ID: &secretName,
Attributes: &enabledAtt,
Tags: map[string]*string{"environment": &environment, "author": &author},
}
secretList := make([]keyvault.SecretItem, 0)
secretList = append(secretList, secretItem)
list := keyvault.SecretListResult{
Value: &secretList,
}
resultPage := keyvault.NewSecretListResultPage(list, getNextPage)
smtc.listOutput = keyvault.NewSecretListResultIterator(resultPage)
smtc.expectedSecret = secretString
smtc.secretOutput = keyvault.SecretBundle{
Value: &secretString,
}
smtc.refFrom.Find.Tags = map[string]string{"environment": environment, "author": author}
smtc.expectedData[secretName] = []byte(secretString)
}
successCases := []*secretManagerTestCase{
makeValidSecretManagerTestCaseCustom(setOneSecretByName),
makeValidSecretManagerTestCaseCustom(setTwoSecretsByName),
makeValidSecretManagerTestCaseCustom(setOneSecretByTag),
makeValidSecretManagerTestCaseCustom(setTwoSecretsByTag),
}
sm := Azure{}
for k, v := range successCases {
sm.baseClient = v.mockClient
out, err := sm.GetAllSecrets(context.Background(), *v.refFrom)
if !utils.ErrorContains(err, v.expectError) {
t.Errorf(unexpectedError, k, err.Error(), v.expectError)
}
if err == nil && !reflect.DeepEqual(out, v.expectedData) {
t.Errorf(unexpectedSecretData, k, v.expectedData, out)
}
}
}

View file

@ -22,6 +22,7 @@ import (
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
"github.com/external-secrets/external-secrets/pkg/provider"
"github.com/external-secrets/external-secrets/pkg/provider/schema"
"github.com/external-secrets/external-secrets/pkg/utils"
)
var _ provider.Provider = &Client{}
@ -31,7 +32,7 @@ type Client struct {
NewFn func(context.Context, esv1alpha1.GenericStore, client.Client,
string) (provider.SecretsClient, error)
GetSecretFn func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error)
GetSecretMapFn func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error)
GetSecretMapFn func(context.Context, esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error)
}
// New returns a fake provider/client.
@ -40,7 +41,7 @@ func New() *Client {
GetSecretFn: func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
return nil, nil
},
GetSecretMapFn: func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
GetSecretMapFn: func(context.Context, esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
return nil, nil
},
}
@ -70,8 +71,15 @@ func (v *Client) WithGetSecret(secData []byte, err error) *Client {
return v
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (v *Client) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
// GetSecretMap imeplements the provider.Provider interface.
func (v *Client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
func (v *Client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
return v.GetSecretMapFn(ctx, ref)
}
func (v *Client) Close(ctx context.Context) error {
@ -80,7 +88,7 @@ func (v *Client) Close(ctx context.Context) error {
// WithGetSecretMap wraps the secret data map returned by this fake provider.
func (v *Client) WithGetSecretMap(secData map[string][]byte, err error) *Client {
v.GetSecretMapFn = func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
v.GetSecretMapFn = func(context.Context, esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
return secData, err
}
return v

View file

@ -199,13 +199,20 @@ func (sm *ProviderGCP) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSec
return []byte(val.String()), nil
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (sm *ProviderGCP) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
// GetSecretMap returns multiple k/v pairs from the provider.
func (sm *ProviderGCP) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
func (sm *ProviderGCP) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
if sm.SecretManagerClient == nil || sm.projectID == "" {
return nil, fmt.Errorf(errUninitalizedGCPProvider)
}
data, err := sm.GetSecret(ctx, ref)
data, err := sm.GetSecret(ctx, ref.GetDataRemoteRef())
if err != nil {
return nil, err
}

View file

@ -24,6 +24,7 @@ import (
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
fakesm "github.com/external-secrets/external-secrets/pkg/provider/gcp/secretmanager/fake"
"github.com/external-secrets/external-secrets/pkg/utils"
)
type secretManagerTestCase struct {
@ -31,6 +32,7 @@ type secretManagerTestCase struct {
apiInput *secretmanagerpb.AccessSecretVersionRequest
apiOutput *secretmanagerpb.AccessSecretVersionResponse
ref *esv1alpha1.ExternalSecretDataRemoteRef
refFrom *esv1alpha1.ExternalSecretDataFromRemoteRef
projectID string
apiErr error
expectError string
@ -43,7 +45,8 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
smtc := secretManagerTestCase{
mockClient: &fakesm.MockSMClient{},
apiInput: makeValidAPIInput(),
ref: makeValidRef(),
ref: utils.MakeValidRefWithParams("/baz", "", "default"),
refFrom: utils.MakeValidRefFromWithParams("/baz", "", "default"),
apiOutput: makeValidAPIOutput(),
projectID: "default",
apiErr: nil,
@ -56,13 +59,6 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
return &smtc
}
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
return &esv1alpha1.ExternalSecretDataRemoteRef{
Key: "/baz",
Version: "default",
}
}
func makeValidAPIInput() *secretmanagerpb.AccessSecretVersionRequest {
return &secretmanagerpb.AccessSecretVersionRequest{
Name: "projects/default/secrets//baz/versions/default",
@ -191,7 +187,7 @@ func TestGetSecretMap(t *testing.T) {
for k, v := range successCases {
sm.projectID = v.projectID
sm.SecretManagerClient = v.mockClient
out, err := sm.GetSecretMap(context.Background(), *v.ref)
out, err := sm.GetSecretMap(context.Background(), *v.refFrom)
if !ErrorContains(err, v.expectError) {
t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
}

View file

@ -185,11 +185,18 @@ func (g *Gitlab) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDat
return []byte(val.String()), nil
}
func (g *Gitlab) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (g *Gitlab) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
func (g *Gitlab) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// Gets a secret as normal, expecting secret value to be a json object
data, err := g.GetSecret(ctx, ref)
data, err := g.GetSecret(ctx, ref.GetDataRemoteRef())
if err != nil {
return nil, fmt.Errorf("error getting secret %s: %w", ref.Key, err)
return nil, fmt.Errorf("error getting secret %s: %w", ref.Extract.Key, err)
}
// Maps the json data to a string:string map

View file

@ -24,6 +24,7 @@ import (
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
fakegitlab "github.com/external-secrets/external-secrets/pkg/provider/gitlab/fake"
"github.com/external-secrets/external-secrets/pkg/utils"
)
type secretManagerTestCase struct {
@ -32,6 +33,7 @@ type secretManagerTestCase struct {
apiInputKey string
apiOutput *gitlab.ProjectVariable
ref *esv1alpha1.ExternalSecretDataRemoteRef
refFrom *esv1alpha1.ExternalSecretDataFromRemoteRef
projectID *string
apiErr error
expectError string
@ -45,7 +47,8 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
mockClient: &fakegitlab.GitlabMockClient{},
apiInputProjectID: makeValidAPIInputProjectID(),
apiInputKey: makeValidAPIInputKey(),
ref: makeValidRef(),
ref: utils.MakeValidRef(),
refFrom: utils.MakeValidRefFrom(),
projectID: nil,
apiOutput: makeValidAPIOutput(),
apiErr: nil,
@ -57,13 +60,6 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
return &smtc
}
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
return &esv1alpha1.ExternalSecretDataRemoteRef{
Key: "test-secret",
Version: "default",
}
}
func makeValidAPIInputProjectID() string {
return "testID"
}
@ -157,7 +153,7 @@ func TestGetSecretMap(t *testing.T) {
sm := Gitlab{}
for k, v := range successCases {
sm.client = v.mockClient
out, err := sm.GetSecretMap(context.Background(), *v.ref)
out, err := sm.GetSecretMap(context.Background(), *v.refFrom)
if !ErrorContains(err, v.expectError) {
t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
}

View file

@ -93,6 +93,13 @@ func (c *client) setAuth(ctx context.Context) error {
return nil
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (ibm *providerIBM) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
func (ibm *providerIBM) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
if utils.IsNil(ibm.IBMClient) {
return nil, fmt.Errorf(errUninitalizedIBMProvider)
@ -126,7 +133,7 @@ func (ibm *providerIBM) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSe
case sm.CreateSecretOptionsSecretTypeImportedCertConst:
if ref.Property == "" {
return nil, fmt.Errorf("remoteRef.property required for secret type imported_cert")
return nil, fmt.Errorf("remoteref.Property required for secret type imported_cert")
}
return getImportCertSecret(ibm, &secretName, ref)
@ -205,13 +212,13 @@ func getUsernamePasswordSecret(ibm *providerIBM, secretName *string, ref esv1alp
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
}
func (ibm *providerIBM) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
func (ibm *providerIBM) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
if utils.IsNil(ibm.IBMClient) {
return nil, fmt.Errorf(errUninitalizedIBMProvider)
}
secretType := sm.GetSecretOptionsSecretTypeArbitraryConst
secretName := ref.Key
secretName := ref.Extract.Key
nameSplitted := strings.Split(secretName, "/")
if len(nameSplitted) > 1 {
@ -224,7 +231,7 @@ func (ibm *providerIBM) GetSecretMap(ctx context.Context, ref esv1alpha1.Externa
response, _, err := ibm.IBMClient.GetSecret(
&sm.GetSecretOptions{
SecretType: core.StringPtr(sm.GetSecretOptionsSecretTypeArbitraryConst),
ID: &ref.Key,
ID: &ref.Extract.Key,
})
if err != nil {
return nil, err

View file

@ -30,6 +30,7 @@ import (
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
v1 "github.com/external-secrets/external-secrets/apis/meta/v1"
fakesm "github.com/external-secrets/external-secrets/pkg/provider/ibm/fake"
"github.com/external-secrets/external-secrets/pkg/utils"
)
type secretManagerTestCase struct {
@ -37,6 +38,7 @@ type secretManagerTestCase struct {
apiInput *sm.GetSecretOptions
apiOutput *sm.GetSecret
ref *esv1alpha1.ExternalSecretDataRemoteRef
refFrom *esv1alpha1.ExternalSecretDataFromRemoteRef
serviceURL *string
apiErr error
expectError string
@ -49,7 +51,8 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
smtc := secretManagerTestCase{
mockClient: &fakesm.IBMMockClient{},
apiInput: makeValidAPIInput(),
ref: makeValidRef(),
ref: utils.MakeValidRef(),
refFrom: utils.MakeValidRefFrom(),
apiOutput: makeValidAPIOutput(),
serviceURL: nil,
apiErr: nil,
@ -61,13 +64,6 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
return &smtc
}
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
return &esv1alpha1.ExternalSecretDataRemoteRef{
Key: "test-secret",
Version: "default",
}
}
func makeValidAPIInput() *sm.GetSecretOptions {
return &sm.GetSecretOptions{
SecretType: core.StringPtr(sm.GetSecretOptionsSecretTypeArbitraryConst),
@ -228,7 +224,7 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst)
smtc.apiOutput.Resources = resources
smtc.ref.Key = secretCert
smtc.expectError = "remoteRef.property required for secret type imported_cert"
smtc.expectError = "remoteref.Property required for secret type imported_cert"
}
successCases := []*secretManagerTestCase{
@ -311,7 +307,7 @@ func TestGetSecretMap(t *testing.T) {
smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
smtc.apiOutput.Resources = resources
smtc.ref.Key = "username_password/test-secret"
smtc.refFrom.Extract.Key = "username_password/test-secret"
smtc.expectedData["username"] = []byte(secretUsername)
smtc.expectedData["password"] = []byte(secretPassword)
}
@ -327,7 +323,7 @@ func TestGetSecretMap(t *testing.T) {
smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst)
smtc.apiOutput.Resources = resources
smtc.ref.Key = "iam_credentials/test-secret"
smtc.refFrom.Extract.Key = "iam_credentials/test-secret"
smtc.expectedData["apikey"] = []byte(secretAPIKey)
}
@ -347,7 +343,7 @@ func TestGetSecretMap(t *testing.T) {
smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst)
smtc.apiOutput.Resources = resources
smtc.ref.Key = "imported_cert/test-secret"
smtc.refFrom.Extract.Key = "imported_cert/test-secret"
smtc.expectedData["certificate"] = []byte(secretCertificate)
smtc.expectedData["private_key"] = []byte(secretPrivateKey)
smtc.expectedData["intermediate"] = []byte(secretIntermediate)
@ -366,7 +362,7 @@ func TestGetSecretMap(t *testing.T) {
sm := providerIBM{}
for k, v := range successCases {
sm.IBMClient = v.mockClient
out, err := sm.GetSecretMap(context.Background(), *v.ref)
out, err := sm.GetSecretMap(context.Background(), *v.refFrom)
if !ErrorContains(err, v.expectError) {
t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
}

View file

@ -162,8 +162,15 @@ func (vms *VaultManagementService) GetSecret(ctx context.Context, ref esv1alpha1
return []byte(val.String()), nil
}
func (vms *VaultManagementService) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
data, err := vms.GetSecret(ctx, ref)
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (vms *VaultManagementService) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
func (vms *VaultManagementService) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
data, err := vms.GetSecret(ctx, ref.GetDataRemoteRef())
if err != nil {
return nil, err
}

View file

@ -24,6 +24,7 @@ import (
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
fakeoracle "github.com/external-secrets/external-secrets/pkg/provider/oracle/fake"
"github.com/external-secrets/external-secrets/pkg/utils"
)
type vaultTestCase struct {
@ -31,6 +32,7 @@ type vaultTestCase struct {
apiInput *secrets.GetSecretBundleByNameRequest
apiOutput *secrets.GetSecretBundleByNameResponse
ref *esv1alpha1.ExternalSecretDataRemoteRef
refFrom *esv1alpha1.ExternalSecretDataFromRemoteRef
apiErr error
expectError string
expectedSecret string
@ -42,7 +44,8 @@ func makeValidVaultTestCase() *vaultTestCase {
smtc := vaultTestCase{
mockClient: &fakeoracle.OracleMockClient{},
apiInput: makeValidAPIInput(),
ref: makeValidRef(),
ref: utils.MakeValidRef(),
refFrom: utils.MakeValidRefFrom(),
apiOutput: makeValidAPIOutput(),
apiErr: nil,
expectError: "",
@ -53,13 +56,6 @@ func makeValidVaultTestCase() *vaultTestCase {
return &smtc
}
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
return &esv1alpha1.ExternalSecretDataRemoteRef{
Key: "test-secret",
Version: "default",
}
}
func makeValidAPIInput() *secrets.GetSecretBundleByNameRequest {
return &secrets.GetSecretBundleByNameRequest{
SecretName: utilpointer.StringPtr("test-secret"),
@ -158,7 +154,7 @@ func TestGetSecretMap(t *testing.T) {
sm := VaultManagementService{}
for k, v := range successCases {
sm.Client = v.mockClient
out, err := sm.GetSecretMap(context.Background(), *v.ref)
out, err := sm.GetSecretMap(context.Background(), *v.refFrom)
if !ErrorContains(err, v.expectError) {
t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
}

View file

@ -34,6 +34,10 @@ type SecretsClient interface {
GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error)
// GetSecretMap returns multiple k/v pairs from the provider
GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error)
GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error)
// GetSecretMap returns all k/v pairs from the provider
GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error)
Close(ctx context.Context) error
}

View file

@ -22,6 +22,7 @@ import (
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
"github.com/external-secrets/external-secrets/pkg/provider"
"github.com/external-secrets/external-secrets/pkg/utils"
)
type PP struct{}
@ -39,10 +40,17 @@ func (p *PP) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRem
}
// GetSecretMap returns multiple k/v pairs from the provider.
func (p *PP) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
func (p *PP) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
return map[string][]byte{}, nil
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (p *PP) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
func (p *PP) Close(ctx context.Context) error {
return nil
}

View file

@ -36,6 +36,7 @@ import (
esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
"github.com/external-secrets/external-secrets/pkg/provider"
"github.com/external-secrets/external-secrets/pkg/provider/schema"
"github.com/external-secrets/external-secrets/pkg/utils"
)
var (
@ -164,8 +165,15 @@ func (v *client) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDat
return value, nil
}
func (v *client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
return v.readSecret(ctx, ref.Key, ref.Version)
func (v *client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
return v.readSecret(ctx, ref.Extract.Key, ref.Extract.Version)
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (v *client) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
func (v *client) Close(ctx context.Context) error {

View file

@ -568,7 +568,7 @@ func TestGetSecretMap(t *testing.T) {
kube kclient.Client
vClient Client
ns string
data esv1alpha1.ExternalSecretDataRemoteRef
dataFrom esv1alpha1.ExternalSecretDataFromRemoteRef
}
type want struct {
@ -671,7 +671,7 @@ func TestGetSecretMap(t *testing.T) {
store: tc.args.store,
namespace: tc.args.ns,
}
_, err := vStore.GetSecretMap(context.Background(), tc.args.data)
_, err := vStore.GetSecretMap(context.Background(), tc.args.dataFrom)
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)
}

View file

@ -37,6 +37,7 @@ import (
"github.com/external-secrets/external-secrets/pkg/provider"
"github.com/external-secrets/external-secrets/pkg/provider/schema"
"github.com/external-secrets/external-secrets/pkg/template"
"github.com/external-secrets/external-secrets/pkg/utils"
)
// Provider satisfies the provider interface.
@ -129,12 +130,12 @@ func (w *WebHook) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDa
return result, nil
}
func (w *WebHook) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
func (w *WebHook) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
provider, err := getProvider(w.store)
if err != nil {
return nil, fmt.Errorf("failed to get store: %w", err)
}
result, err := w.getWebhookData(ctx, provider, ref)
result, err := w.getWebhookData(ctx, provider, ref.GetDataRemoteRef())
if err != nil {
return nil, err
}
@ -373,6 +374,13 @@ func (w *WebHook) getCertFromConfigMap(provider *esv1alpha1.WebhookProvider) ([]
return []byte(val), nil
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (w *WebHook) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
func (w *WebHook) Close(ctx context.Context) error {
return nil
}

View file

@ -269,9 +269,11 @@ func runTestCase(tc testCase, t *testing.T) {
}
func testGetSecretMap(tc testCase, t *testing.T, client provider.SecretsClient) {
testRef := esv1alpha1.ExternalSecretDataRemoteRef{
testRef := esv1alpha1.ExternalSecretDataFromRemoteRef{
Extract: esv1alpha1.ExternalSecretExtract{
Key: tc.Args.Key,
Version: tc.Args.Version,
},
}
secretmap, err := client.GetSecretMap(context.Background(), testRef)
errStr := ""

View file

@ -34,6 +34,7 @@ import (
"github.com/external-secrets/external-secrets/pkg/provider/schema"
"github.com/external-secrets/external-secrets/pkg/provider/yandex/lockbox/client"
"github.com/external-secrets/external-secrets/pkg/provider/yandex/lockbox/client/grpc"
"github.com/external-secrets/external-secrets/pkg/utils"
)
const maxSecretsClientLifetime = 5 * time.Minute // supposed SecretsClient lifetime is quite short
@ -254,9 +255,16 @@ func (c *lockboxSecretsClient) GetSecret(ctx context.Context, ref esv1alpha1.Ext
return getValueAsBinary(entry)
}
// Implements store.Client.GetAllSecrets Interface.
// New version of GetAllSecrets.
func (c *lockboxSecretsClient) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
// TO be implemented
return nil, utils.ThrowNotImplemented()
}
// GetSecretMap returns multiple k/v pairs from the provider.
func (c *lockboxSecretsClient) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
entries, err := c.lockboxClient.GetPayloadEntries(ctx, c.iamToken, ref.Key, ref.Version)
func (c *lockboxSecretsClient) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataFromRemoteRef) (map[string][]byte, error) {
entries, err := c.lockboxClient.GetPayloadEntries(ctx, c.iamToken, ref.Extract.Key, ref.Extract.Version)
if err != nil {
return nil, fmt.Errorf("unable to request secret payload to get secret map: %w", err)
}

View file

@ -131,7 +131,7 @@ func TestGetSecretForAllEntries(t *testing.T) {
})
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
tassert.Nil(t, err)
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID})
data, err := secretsClient.GetSecret(ctx, getRemoteDef(secretID, "", ""))
tassert.Nil(t, err)
tassert.Equal(
@ -169,7 +169,7 @@ func TestGetSecretForTextEntry(t *testing.T) {
})
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
tassert.Nil(t, err)
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
data, err := secretsClient.GetSecret(ctx, getRemoteDef(secretID, k1, ""))
tassert.Nil(t, err)
tassert.Equal(t, v1, string(data))
@ -200,7 +200,7 @@ func TestGetSecretForBinaryEntry(t *testing.T) {
})
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
tassert.Nil(t, err)
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k2})
data, err := secretsClient.GetSecret(ctx, getRemoteDef(secretID, k2, ""))
tassert.Nil(t, err)
tassert.Equal(t, v2, data)
@ -229,7 +229,7 @@ func TestGetSecretByVersionID(t *testing.T) {
})
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
tassert.Nil(t, err)
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
data, err := secretsClient.GetSecret(ctx, getRemoteDef(secretID, "", oldVersionID))
tassert.Nil(t, err)
tassert.Equal(t, map[string]string{oldKey: oldVal}, unmarshalStringMap(t, data))
@ -239,11 +239,11 @@ func TestGetSecretByVersionID(t *testing.T) {
textEntry(newKey, newVal),
)
data, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
data, err = secretsClient.GetSecret(ctx, getRemoteDef(secretID, "", oldVersionID))
tassert.Nil(t, err)
tassert.Equal(t, map[string]string{oldKey: oldVal}, unmarshalStringMap(t, data))
data, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: newVersionID})
data, err = secretsClient.GetSecret(ctx, getRemoteDef(secretID, "", newVersionID))
tassert.Nil(t, err)
tassert.Equal(t, map[string]string{newKey: newVal}, unmarshalStringMap(t, data))
}
@ -271,7 +271,7 @@ func TestGetSecretUnauthorized(t *testing.T) {
})
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
tassert.Nil(t, err)
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID})
_, err = secretsClient.GetSecret(ctx, getRemoteDef(secretID, "", ""))
tassert.EqualError(t, err, errSecretPayloadPermissionDenied)
}
@ -294,13 +294,13 @@ func TestGetSecretNotFound(t *testing.T) {
})
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
tassert.Nil(t, err)
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: "no-secret-with-this-id"})
_, err = secretsClient.GetSecret(ctx, getRemoteDef("no-secret-with-this-id", "", ""))
tassert.EqualError(t, err, errSecretPayloadNotFound)
secretID, _ := lockboxBackend.CreateSecret(authorizedKey,
textEntry("k1", "v1"),
)
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: "no-version-with-this-id"})
_, err = secretsClient.GetSecret(ctx, getRemoteDef(secretID, "", "no-version-with-this-id"))
tassert.EqualError(t, err, "unable to request secret payload to get secret: version not found")
}
@ -339,17 +339,17 @@ func TestGetSecretWithTwoNamespaces(t *testing.T) {
secretsClient2, err := provider.NewClient(ctx, store2, k8sClient, namespace2)
tassert.Nil(t, err)
data, err := secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
data, err := secretsClient1.GetSecret(ctx, getRemoteDef(secretID1, k1, ""))
tassert.Equal(t, v1, string(data))
tassert.Nil(t, err)
data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
data, err = secretsClient1.GetSecret(ctx, getRemoteDef(secretID2, k2, ""))
tassert.Nil(t, data)
tassert.EqualError(t, err, errSecretPayloadPermissionDenied)
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
data, err = secretsClient2.GetSecret(ctx, getRemoteDef(secretID1, k1, ""))
tassert.Nil(t, data)
tassert.EqualError(t, err, errSecretPayloadPermissionDenied)
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
data, err = secretsClient2.GetSecret(ctx, getRemoteDef(secretID2, k2, ""))
tassert.Equal(t, v2, string(data))
tassert.Nil(t, err)
}
@ -400,17 +400,17 @@ func TestGetSecretWithTwoApiEndpoints(t *testing.T) {
var data []byte
data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
data, err = secretsClient1.GetSecret(ctx, getRemoteDef(secretID1, k1, ""))
tassert.Equal(t, v1, string(data))
tassert.Nil(t, err)
data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
data, err = secretsClient1.GetSecret(ctx, getRemoteDef(secretID2, k2, ""))
tassert.Nil(t, data)
tassert.EqualError(t, err, errSecretPayloadNotFound)
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
data, err = secretsClient2.GetSecret(ctx, getRemoteDef(secretID1, k1, ""))
tassert.Nil(t, data)
tassert.EqualError(t, err, errSecretPayloadNotFound)
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
data, err = secretsClient2.GetSecret(ctx, getRemoteDef(secretID2, k2, ""))
tassert.Equal(t, v2, string(data))
tassert.Nil(t, err)
}
@ -442,19 +442,19 @@ func TestGetSecretWithIamTokenExpiration(t *testing.T) {
oldSecretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
tassert.Nil(t, err)
data, err = oldSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
data, err = oldSecretsClient.GetSecret(ctx, getRemoteDef(secretID, k1, ""))
tassert.Equal(t, v1, string(data))
tassert.Nil(t, err)
lockboxBackend.AdvanceClock(2 * tokenExpirationTime)
data, err = oldSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
data, err = oldSecretsClient.GetSecret(ctx, getRemoteDef(secretID, k1, ""))
tassert.Nil(t, data)
tassert.EqualError(t, err, "unable to request secret payload to get secret: iam token expired")
newSecretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
tassert.Nil(t, err)
data, err = newSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
data, err = newSecretsClient.GetSecret(ctx, getRemoteDef(secretID, k1, ""))
tassert.Equal(t, v1, string(data))
tassert.Nil(t, err)
}
@ -499,7 +499,7 @@ func TestGetSecretWithIamTokenCleanup(t *testing.T) {
// Access secretID1 with authorizedKey1, IAM token for authorizedKey1 should be cached
secretsClient, err := provider.NewClient(ctx, store1, k8sClient, namespace)
tassert.Nil(t, err)
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1})
_, err = secretsClient.GetSecret(ctx, getRemoteDef(secretID1, "", ""))
tassert.Nil(t, err)
tassert.True(t, provider.isIamTokenCached(authorizedKey1))
@ -510,7 +510,7 @@ func TestGetSecretWithIamTokenCleanup(t *testing.T) {
// Access secretID2 with authorizedKey2, IAM token for authorizedKey2 should be cached
secretsClient, err = provider.NewClient(ctx, store2, k8sClient, namespace)
tassert.Nil(t, err)
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2})
_, err = secretsClient.GetSecret(ctx, getRemoteDef(secretID2, "", ""))
tassert.Nil(t, err)
tassert.True(t, provider.isIamTokenCached(authorizedKey1))
@ -562,7 +562,7 @@ func TestGetSecretMap(t *testing.T) {
})
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
tassert.Nil(t, err)
data, err := secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID})
data, err := secretsClient.GetSecretMap(ctx, getRemoteFromDef(secretID, "", ""))
tassert.Nil(t, err)
tassert.Equal(
@ -598,7 +598,7 @@ func TestGetSecretMapByVersionID(t *testing.T) {
})
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
tassert.Nil(t, err)
data, err := secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
data, err := secretsClient.GetSecretMap(ctx, getRemoteFromDef(secretID, "", oldVersionID))
tassert.Nil(t, err)
tassert.Equal(t, map[string][]byte{oldKey: []byte(oldVal)}, data)
@ -608,11 +608,11 @@ func TestGetSecretMapByVersionID(t *testing.T) {
textEntry(newKey, newVal),
)
data, err = secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
data, err = secretsClient.GetSecretMap(ctx, getRemoteFromDef(secretID, "", oldVersionID))
tassert.Nil(t, err)
tassert.Equal(t, map[string][]byte{oldKey: []byte(oldVal)}, data)
data, err = secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: newVersionID})
data, err = secretsClient.GetSecretMap(ctx, getRemoteFromDef(secretID, "", newVersionID))
tassert.Nil(t, err)
tassert.Equal(t, map[string][]byte{newKey: []byte(newVal)}, data)
}
@ -640,6 +640,24 @@ func newYandexLockboxSecretStore(apiEndpoint, namespace, authorizedKeySecretName
}
}
func getRemoteDef(key, property, version string) esv1alpha1.ExternalSecretDataRemoteRef {
return esv1alpha1.ExternalSecretDataRemoteRef{
Key: key,
Property: property,
Version: version,
}
}
func getRemoteFromDef(key, property, version string) esv1alpha1.ExternalSecretDataFromRemoteRef {
return esv1alpha1.ExternalSecretDataFromRemoteRef{
Extract: esv1alpha1.ExternalSecretExtract{
Key: key,
Property: property,
Version: version,
},
}
}
func createK8sSecret(ctx context.Context, k8sClient client.Client, namespace, secretName, secretKey string, secretContent interface{}) error {
data, err := json.Marshal(secretContent)
if err != nil {

View file

@ -20,7 +20,16 @@ import (
"crypto/md5"
"fmt"
"reflect"
"runtime"
"strings"
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
)
const (
notImplemented = "not implemented: %s"
testSecret = "test-secret"
defaultVersion = "default"
)
// MergeByteMap merges map of byte slices.
@ -66,3 +75,37 @@ func ErrorContains(out error, want string) bool {
}
return strings.Contains(out.Error(), want)
}
func MakeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
return MakeValidRefWithParams(testSecret, "", defaultVersion)
}
func MakeValidRefWithParams(key, property, version string) *esv1alpha1.ExternalSecretDataRemoteRef {
return &esv1alpha1.ExternalSecretDataRemoteRef{
Key: key,
Property: property,
Version: version,
}
}
func MakeValidRefFrom() *esv1alpha1.ExternalSecretDataFromRemoteRef {
return MakeValidRefFromWithParams(testSecret, "", defaultVersion)
}
func MakeValidRefFromWithParams(key, property, version string) *esv1alpha1.ExternalSecretDataFromRemoteRef {
return &esv1alpha1.ExternalSecretDataFromRemoteRef{
Extract: esv1alpha1.ExternalSecretExtract{
Key: key,
Property: property,
Version: version,
},
}
}
func ThrowNotImplemented() error {
pc := make([]uintptr, 10) // at least 1 entry needed
runtime.Callers(2, pc)
f := runtime.FuncForPC(pc[0])
return fmt.Errorf(notImplemented, f.Name())
}