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:
commit
ca0cda7c16
48 changed files with 1073 additions and 211 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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`
|
||||
|
||||
|
|
70
docs/guides-multiple-secrets.md
Normal file
70
docs/guides-multiple-secrets.md
Normal 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="
|
||||
}
|
||||
```
|
BIN
docs/pictures/screenshot_akv_secrets.png
Normal file
BIN
docs/pictures/screenshot_akv_secrets.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 152 KiB |
|
@ -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
|
||||
|
|
20
docs/snippets/akv-data-from-external-secret.yaml
Normal file
20
docs/snippets/akv-data-from-external-secret.yaml
Normal 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
|
|
@ -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"
|
|
@ -17,4 +17,5 @@ spec:
|
|||
version: provider-key-version
|
||||
property: provider-key-property
|
||||
dataFrom:
|
||||
- key: remote-key-in-the-provider
|
||||
- extract:
|
||||
key: provider-key
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
186
docs/spec.md
186
docs/spec.md
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 := ""
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue