mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-14 11:57:59 +00:00
Merge pull request #661 from external-secrets/feature/fake-provider
feat(provider): implement fake provider
This commit is contained in:
commit
410908dd9f
16 changed files with 898 additions and 71 deletions
27
apis/externalsecrets/v1alpha1/secretstore_fake_types.go
Normal file
27
apis/externalsecrets/v1alpha1/secretstore_fake_types.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
// FakeProvider configures a fake provider that returns static values.
|
||||||
|
type FakeProvider struct {
|
||||||
|
Data []FakeProviderData `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FakeProviderData struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value,omitempty"`
|
||||||
|
ValueMap map[string]string `json:"valueMap,omitempty"`
|
||||||
|
Version string `json:"version,omitempty"`
|
||||||
|
}
|
|
@ -81,6 +81,10 @@ type SecretStoreProvider struct {
|
||||||
// Webhook configures this store to sync secrets using a generic templated webhook
|
// Webhook configures this store to sync secrets using a generic templated webhook
|
||||||
// +optional
|
// +optional
|
||||||
Webhook *WebhookProvider `json:"webhook,omitempty"`
|
Webhook *WebhookProvider `json:"webhook,omitempty"`
|
||||||
|
|
||||||
|
// Fake configures a store with static key/value pairs
|
||||||
|
// +optional
|
||||||
|
Fake *FakeProvider `json:"fake,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SecretStoreRetrySettings struct {
|
type SecretStoreRetrySettings struct {
|
||||||
|
|
|
@ -599,6 +599,50 @@ func (in *ExternalSecretTemplateMetadata) DeepCopy() *ExternalSecretTemplateMeta
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *FakeProvider) DeepCopyInto(out *FakeProvider) {
|
||||||
|
*out = *in
|
||||||
|
if in.Data != nil {
|
||||||
|
in, out := &in.Data, &out.Data
|
||||||
|
*out = make([]FakeProviderData, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FakeProvider.
|
||||||
|
func (in *FakeProvider) DeepCopy() *FakeProvider {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(FakeProvider)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *FakeProviderData) DeepCopyInto(out *FakeProviderData) {
|
||||||
|
*out = *in
|
||||||
|
if in.ValueMap != nil {
|
||||||
|
in, out := &in.ValueMap, &out.ValueMap
|
||||||
|
*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 FakeProviderData.
|
||||||
|
func (in *FakeProviderData) DeepCopy() *FakeProviderData {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(FakeProviderData)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *GCPSMAuth) DeepCopyInto(out *GCPSMAuth) {
|
func (in *GCPSMAuth) DeepCopyInto(out *GCPSMAuth) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
@ -939,6 +983,11 @@ func (in *SecretStoreProvider) DeepCopyInto(out *SecretStoreProvider) {
|
||||||
*out = new(WebhookProvider)
|
*out = new(WebhookProvider)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.Fake != nil {
|
||||||
|
in, out := &in.Fake, &out.Fake
|
||||||
|
*out = new(FakeProvider)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretStoreProvider.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretStoreProvider.
|
||||||
|
|
|
@ -380,6 +380,29 @@ spec:
|
||||||
required:
|
required:
|
||||||
- vaultUrl
|
- vaultUrl
|
||||||
type: object
|
type: object
|
||||||
|
fake:
|
||||||
|
description: Fake configures a store with static key/value pairs
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
items:
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
type: string
|
||||||
|
value:
|
||||||
|
type: string
|
||||||
|
valueMap:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
version:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- key
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- data
|
||||||
|
type: object
|
||||||
gcpsm:
|
gcpsm:
|
||||||
description: GCPSM configures this store to sync secrets using
|
description: GCPSM configures this store to sync secrets using
|
||||||
Google Cloud Platform Secret Manager provider
|
Google Cloud Platform Secret Manager provider
|
||||||
|
|
|
@ -380,6 +380,29 @@ spec:
|
||||||
required:
|
required:
|
||||||
- vaultUrl
|
- vaultUrl
|
||||||
type: object
|
type: object
|
||||||
|
fake:
|
||||||
|
description: Fake configures a store with static key/value pairs
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
items:
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
type: string
|
||||||
|
value:
|
||||||
|
type: string
|
||||||
|
valueMap:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
version:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- key
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- data
|
||||||
|
type: object
|
||||||
gcpsm:
|
gcpsm:
|
||||||
description: GCPSM configures this store to sync secrets using
|
description: GCPSM configures this store to sync secrets using
|
||||||
Google Cloud Platform Secret Manager provider
|
Google Cloud Platform Secret Manager provider
|
||||||
|
|
26
docs/provider-fake.md
Normal file
26
docs/provider-fake.md
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
We provide a `fake` implementation to help with testing. This provider returns static key/value pairs and nothing else.
|
||||||
|
To use the `fake` provider simply create a `SecretStore` or `ClusterSecretStore` and configure it like in the following example:
|
||||||
|
|
||||||
|
!!! note inline end
|
||||||
|
The provider returns static data configured in `value` or `valueMap`. You can define a `version`, too. If set the `remoteRef` from an ExternalSecret must match otherwise no value is returned.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
{% include 'fake-provider-store.yaml' %}
|
||||||
|
```
|
||||||
|
|
||||||
|
Please note that `value` is intended for exclusive use with `data` and `valueMap` for `dataFrom`.
|
||||||
|
Here is an example `ExternalSecret` that displays this behavior:
|
||||||
|
|
||||||
|
!!! warning inline end
|
||||||
|
This provider supports specifying different `data[].version` configurations. However, `data[].property` is ignored.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
{% include 'fake-provider-es.yaml' %}
|
||||||
|
```
|
||||||
|
|
||||||
|
This results in the following secret:
|
||||||
|
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
{% include 'fake-provider-secret.yaml' %}
|
||||||
|
```
|
18
docs/snippets/fake-provider-es.yaml
Normal file
18
docs/snippets/fake-provider-es.yaml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
apiVersion: external-secrets.io/v1alpha1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: example
|
||||||
|
spec:
|
||||||
|
refreshInterval: 1h
|
||||||
|
secretStoreRef:
|
||||||
|
name: fake
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
target:
|
||||||
|
name: secret-to-be-created
|
||||||
|
data:
|
||||||
|
- secretKey: foo_bar
|
||||||
|
remoteRef:
|
||||||
|
key: /foo/bar
|
||||||
|
version: v1
|
||||||
|
dataFrom:
|
||||||
|
- key: /foo/baz
|
9
docs/snippets/fake-provider-secret.yaml
Normal file
9
docs/snippets/fake-provider-secret.yaml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: secret-to-be-created
|
||||||
|
namespace: default
|
||||||
|
data:
|
||||||
|
foo_bar: SEVMTE8x # HELLO1 (via data)
|
||||||
|
foo: ZXhhbXBsZQ== # example (via dataFrom)
|
||||||
|
other: dGhpbmc= # thing (via dataFrom)
|
20
docs/snippets/fake-provider-store.yaml
Normal file
20
docs/snippets/fake-provider-store.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
apiVersion: external-secrets.io/v1alpha1
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
metadata:
|
||||||
|
name: fake
|
||||||
|
spec:
|
||||||
|
provider:
|
||||||
|
fake:
|
||||||
|
data:
|
||||||
|
- key: "/foo/bar"
|
||||||
|
value: "HELLO1"
|
||||||
|
version: "v1"
|
||||||
|
- key: "/foo/bar"
|
||||||
|
value: "HELLO2"
|
||||||
|
version: "v2"
|
||||||
|
- key: "/foo/baz"
|
||||||
|
valueMap:
|
||||||
|
foo: example
|
||||||
|
other: thing
|
||||||
|
|
||||||
|
|
336
docs/spec.md
336
docs/spec.md
|
@ -714,6 +714,237 @@ string
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr></tbody>
|
</tr></tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<h3 id="external-secrets.io/v1alpha1.ClusterExternalSecret">ClusterExternalSecret
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
<p>ClusterExternalSecret is the Schema for the clusterexternalsecrets API.</p>
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Field</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>metadata</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta">
|
||||||
|
Kubernetes meta/v1.ObjectMeta
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Refer to the Kubernetes API documentation for the fields of the
|
||||||
|
<code>metadata</code> field.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>spec</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.ClusterExternalSecretSpec">
|
||||||
|
ClusterExternalSecretSpec
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>externalSecretSpec</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.ExternalSecretSpec">
|
||||||
|
ExternalSecretSpec
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>The spec for the ExternalSecrets to be created</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>externalSecretName</code></br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>The name of the external secrets to be created defaults to the name of the ClusterExternalSecret</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>namespaceSelector</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#labelselector-v1-meta">
|
||||||
|
Kubernetes meta/v1.LabelSelector
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>The labels to select by to find the Namespaces to create the ExternalSecrets in.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>status</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.ClusterExternalSecretStatus">
|
||||||
|
ClusterExternalSecretStatus
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h3 id="external-secrets.io/v1alpha1.ClusterExternalSecretConditionType">ClusterExternalSecretConditionType
|
||||||
|
(<code>string</code> alias)</p></h3>
|
||||||
|
<p>
|
||||||
|
(<em>Appears on:</em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.ClusterExternalSecretStatus">ClusterExternalSecretStatus</a>)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Value</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody><tr><td><p>"NotReady"</p></td>
|
||||||
|
<td></td>
|
||||||
|
</tr><tr><td><p>"PartiallyReady"</p></td>
|
||||||
|
<td></td>
|
||||||
|
</tr><tr><td><p>"Ready"</p></td>
|
||||||
|
<td></td>
|
||||||
|
</tr></tbody>
|
||||||
|
</table>
|
||||||
|
<h3 id="external-secrets.io/v1alpha1.ClusterExternalSecretSpec">ClusterExternalSecretSpec
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
(<em>Appears on:</em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.ClusterExternalSecret">ClusterExternalSecret</a>)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<p>ClusterExternalSecretSpec defines the desired state of ClusterExternalSecret.</p>
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Field</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>externalSecretSpec</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.ExternalSecretSpec">
|
||||||
|
ExternalSecretSpec
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>The spec for the ExternalSecrets to be created</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>externalSecretName</code></br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>The name of the external secrets to be created defaults to the name of the ClusterExternalSecret</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>namespaceSelector</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#labelselector-v1-meta">
|
||||||
|
Kubernetes meta/v1.LabelSelector
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>The labels to select by to find the Namespaces to create the ExternalSecrets in.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h3 id="external-secrets.io/v1alpha1.ClusterExternalSecretStatus">ClusterExternalSecretStatus
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
(<em>Appears on:</em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.ClusterExternalSecret">ClusterExternalSecret</a>)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<p>ClusterExternalSecretStatus defines the observed state of ClusterExternalSecret.</p>
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Field</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>type</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.ClusterExternalSecretConditionType">
|
||||||
|
ClusterExternalSecretConditionType
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>status</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#conditionstatus-v1-core">
|
||||||
|
Kubernetes core/v1.ConditionStatus
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>externalSecretStatuses</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.ExternalSecretStatus">
|
||||||
|
[]ExternalSecretStatus
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
<h3 id="external-secrets.io/v1alpha1.ClusterSecretStore">ClusterSecretStore
|
<h3 id="external-secrets.io/v1alpha1.ClusterSecretStore">ClusterSecretStore
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
|
@ -1084,6 +1315,7 @@ string
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
(<em>Appears on:</em>
|
(<em>Appears on:</em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.ClusterExternalSecretSpec">ClusterExternalSecretSpec</a>,
|
||||||
<a href="#external-secrets.io/v1alpha1.ExternalSecret">ExternalSecret</a>)
|
<a href="#external-secrets.io/v1alpha1.ExternalSecret">ExternalSecret</a>)
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
@ -1171,6 +1403,7 @@ If multiple entries are specified, the Secret keys are merged in the specified o
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
(<em>Appears on:</em>
|
(<em>Appears on:</em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.ClusterExternalSecretStatus">ClusterExternalSecretStatus</a>,
|
||||||
<a href="#external-secrets.io/v1alpha1.ExternalSecret">ExternalSecret</a>)
|
<a href="#external-secrets.io/v1alpha1.ExternalSecret">ExternalSecret</a>)
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
@ -1486,6 +1719,95 @@ map[string]string
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<h3 id="external-secrets.io/v1alpha1.FakeProvider">FakeProvider
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
(<em>Appears on:</em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.SecretStoreProvider">SecretStoreProvider</a>)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<p>FakeProvider configures a fake provider that returns static values</p>
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Field</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>data</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.FakeProviderData">
|
||||||
|
[]FakeProviderData
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h3 id="external-secrets.io/v1alpha1.FakeProviderData">FakeProviderData
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
(<em>Appears on:</em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.FakeProvider">FakeProvider</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>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>value</code></br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>valueMap</code></br>
|
||||||
|
<em>
|
||||||
|
map[string]string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>version</code></br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
<h3 id="external-secrets.io/v1alpha1.GCPSMAuth">GCPSMAuth
|
<h3 id="external-secrets.io/v1alpha1.GCPSMAuth">GCPSMAuth
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
|
@ -2310,6 +2632,20 @@ WebhookProvider
|
||||||
<p>Webhook configures this store to sync secrets using a generic templated webhook</p>
|
<p>Webhook configures this store to sync secrets using a generic templated webhook</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>fake</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1alpha1.FakeProvider">
|
||||||
|
FakeProvider
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>Fake configures a store with static key/value pairs</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<h3 id="external-secrets.io/v1alpha1.SecretStoreRef">SecretStoreRef
|
<h3 id="external-secrets.io/v1alpha1.SecretStoreRef">SecretStoreRef
|
||||||
|
|
|
@ -56,6 +56,7 @@ nav:
|
||||||
- Oracle:
|
- Oracle:
|
||||||
- Oracle Vault: provider-oracle-vault.md
|
- Oracle Vault: provider-oracle-vault.md
|
||||||
- Webhook: provider-webhook.md
|
- Webhook: provider-webhook.md
|
||||||
|
- Fake: provider-fake.md
|
||||||
- References:
|
- References:
|
||||||
- API specification: spec.md
|
- API specification: spec.md
|
||||||
- Contributing:
|
- Contributing:
|
||||||
|
|
|
@ -31,8 +31,8 @@ import (
|
||||||
|
|
||||||
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
|
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"
|
||||||
"github.com/external-secrets/external-secrets/pkg/provider/fake"
|
|
||||||
"github.com/external-secrets/external-secrets/pkg/provider/schema"
|
"github.com/external-secrets/external-secrets/pkg/provider/schema"
|
||||||
|
"github.com/external-secrets/external-secrets/pkg/provider/testing/fake"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -16,6 +16,7 @@ package fake
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
|
@ -24,80 +25,72 @@ import (
|
||||||
"github.com/external-secrets/external-secrets/pkg/provider/schema"
|
"github.com/external-secrets/external-secrets/pkg/provider/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ provider.Provider = &Client{}
|
var (
|
||||||
|
errNotFound = fmt.Errorf("secret value not found")
|
||||||
|
errMissingStore = fmt.Errorf("missing store provider")
|
||||||
|
errMissingFakeProvider = fmt.Errorf("missing store provider fake")
|
||||||
|
)
|
||||||
|
|
||||||
// Client is a fake client for testing.
|
type Provider struct {
|
||||||
type Client struct {
|
config *esv1alpha1.FakeProvider
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a fake provider/client.
|
func (p *Provider) NewClient(ctx context.Context, store esv1alpha1.GenericStore, kube client.Client, namespace string) (provider.SecretsClient, error) {
|
||||||
func New() *Client {
|
cfg, err := getProvider(store)
|
||||||
v := &Client{
|
|
||||||
GetSecretFn: func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
GetSecretMapFn: func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
v.NewFn = func(context.Context, esv1alpha1.GenericStore, client.Client, string) (provider.SecretsClient, error) {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterAs registers the fake client in the schema.
|
|
||||||
func (v *Client) RegisterAs(provider *esv1alpha1.SecretStoreProvider) {
|
|
||||||
schema.ForceRegister(v, provider)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSecret implements the provider.Provider interface.
|
|
||||||
func (v *Client) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
|
|
||||||
return v.GetSecretFn(ctx, ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithGetSecret wraps secret data returned by this provider.
|
|
||||||
func (v *Client) WithGetSecret(secData []byte, err error) *Client {
|
|
||||||
v.GetSecretFn = func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
|
|
||||||
return secData, err
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSecretMap imeplements the provider.Provider interface.
|
|
||||||
func (v *Client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
|
||||||
return v.GetSecretMapFn(ctx, ref)
|
|
||||||
}
|
|
||||||
func (v *Client) Close(ctx context.Context) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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) {
|
|
||||||
return secData, err
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithNew wraps the fake provider factory function.
|
|
||||||
func (v *Client) WithNew(f func(context.Context, esv1alpha1.GenericStore, client.Client,
|
|
||||||
string) (provider.SecretsClient, error)) *Client {
|
|
||||||
v.NewFn = f
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClient returns a new fake provider.
|
|
||||||
func (v *Client) NewClient(ctx context.Context, store esv1alpha1.GenericStore, kube client.Client, namespace string) (provider.SecretsClient, error) {
|
|
||||||
c, err := v.NewFn(ctx, store, kube, namespace)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return c, nil
|
return &Provider{
|
||||||
|
config: cfg,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProvider(store esv1alpha1.GenericStore) (*esv1alpha1.FakeProvider, error) {
|
||||||
|
if store == nil {
|
||||||
|
return nil, errMissingStore
|
||||||
|
}
|
||||||
|
spc := store.GetSpec()
|
||||||
|
if spc == nil || spc.Provider == nil || spc.Provider.Fake == nil {
|
||||||
|
return nil, errMissingFakeProvider
|
||||||
|
}
|
||||||
|
return spc.Provider.Fake, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSecret returns a single secret from the provider.
|
||||||
|
func (p *Provider) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
|
||||||
|
for _, data := range p.config.Data {
|
||||||
|
if data.Key == ref.Key && data.Version == ref.Version {
|
||||||
|
return []byte(data.Value), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, errNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSecretMap returns multiple k/v pairs from the provider.
|
||||||
|
func (p *Provider) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
||||||
|
for _, data := range p.config.Data {
|
||||||
|
if data.Key != ref.Key || data.Version != ref.Version || data.ValueMap == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return convertMap(data.ValueMap), nil
|
||||||
|
}
|
||||||
|
return nil, errNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertMap(in map[string]string) map[string][]byte {
|
||||||
|
m := make(map[string][]byte)
|
||||||
|
for k, v := range in {
|
||||||
|
m[k] = []byte(v)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Provider) Close(ctx context.Context) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
schema.Register(&Provider{}, &esv1alpha1.SecretStoreProvider{
|
||||||
|
Fake: &esv1alpha1.FakeProvider{},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
194
pkg/provider/fake/fake_test.go
Normal file
194
pkg/provider/fake/fake_test.go
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
/*
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
package fake
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/onsi/gomega"
|
||||||
|
|
||||||
|
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewClient(t *testing.T) {
|
||||||
|
p := &Provider{}
|
||||||
|
gomega.RegisterTestingT(t)
|
||||||
|
|
||||||
|
// nil store
|
||||||
|
_, err := p.NewClient(context.Background(), nil, nil, "")
|
||||||
|
gomega.Expect(err).To(gomega.HaveOccurred())
|
||||||
|
|
||||||
|
// missing provider
|
||||||
|
_, err = p.NewClient(context.Background(), &esv1alpha1.SecretStore{}, nil, "")
|
||||||
|
gomega.Expect(err).To(gomega.HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClose(t *testing.T) {
|
||||||
|
p := &Provider{}
|
||||||
|
gomega.RegisterTestingT(t)
|
||||||
|
err := p.Close(context.TODO())
|
||||||
|
gomega.Expect(err).ToNot(gomega.HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
type testCase struct {
|
||||||
|
name string
|
||||||
|
input []esv1alpha1.FakeProviderData
|
||||||
|
request esv1alpha1.ExternalSecretDataRemoteRef
|
||||||
|
expValue string
|
||||||
|
expErr string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetSecret(t *testing.T) {
|
||||||
|
gomega.RegisterTestingT(t)
|
||||||
|
p := &Provider{}
|
||||||
|
tbl := []testCase{
|
||||||
|
{
|
||||||
|
name: "return err when not found",
|
||||||
|
input: []esv1alpha1.FakeProviderData{},
|
||||||
|
request: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||||
|
Key: "/foo",
|
||||||
|
Version: "v2",
|
||||||
|
},
|
||||||
|
expErr: "secret value not found",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "get correct value from multiple versions",
|
||||||
|
input: []esv1alpha1.FakeProviderData{
|
||||||
|
{
|
||||||
|
Key: "/foo",
|
||||||
|
Value: "bar2",
|
||||||
|
Version: "v2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "junk",
|
||||||
|
Value: "xxxxx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "/foo",
|
||||||
|
Value: "bar1",
|
||||||
|
Version: "v1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
request: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||||
|
Key: "/foo",
|
||||||
|
Version: "v2",
|
||||||
|
},
|
||||||
|
expValue: "bar2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, row := range tbl {
|
||||||
|
t.Run(row.name, func(t *testing.T) {
|
||||||
|
cl, err := p.NewClient(context.Background(), &esv1alpha1.SecretStore{
|
||||||
|
Spec: esv1alpha1.SecretStoreSpec{
|
||||||
|
Provider: &esv1alpha1.SecretStoreProvider{
|
||||||
|
Fake: &esv1alpha1.FakeProvider{
|
||||||
|
Data: row.input,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil, "")
|
||||||
|
gomega.Expect(err).ToNot(gomega.HaveOccurred())
|
||||||
|
out, err := cl.GetSecret(context.Background(), row.request)
|
||||||
|
if row.expErr != "" {
|
||||||
|
gomega.Expect(err).To(gomega.MatchError(row.expErr))
|
||||||
|
} else {
|
||||||
|
gomega.Expect(err).ToNot(gomega.HaveOccurred())
|
||||||
|
}
|
||||||
|
gomega.Expect(string(out)).To(gomega.Equal(row.expValue))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testMapCase struct {
|
||||||
|
name string
|
||||||
|
input []esv1alpha1.FakeProviderData
|
||||||
|
request esv1alpha1.ExternalSecretDataRemoteRef
|
||||||
|
expValue map[string][]byte
|
||||||
|
expErr string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetSecretMap(t *testing.T) {
|
||||||
|
gomega.RegisterTestingT(t)
|
||||||
|
p := &Provider{}
|
||||||
|
tbl := []testMapCase{
|
||||||
|
{
|
||||||
|
name: "return err when not found",
|
||||||
|
input: []esv1alpha1.FakeProviderData{},
|
||||||
|
request: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||||
|
Key: "/foo",
|
||||||
|
Version: "v2",
|
||||||
|
},
|
||||||
|
expErr: "secret value not found",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "get correct value from multiple versions",
|
||||||
|
input: []esv1alpha1.FakeProviderData{
|
||||||
|
{
|
||||||
|
Key: "junk",
|
||||||
|
ValueMap: map[string]string{
|
||||||
|
"junk": "ok",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "/foo",
|
||||||
|
ValueMap: map[string]string{
|
||||||
|
"foo": "bar",
|
||||||
|
"baz": "bang",
|
||||||
|
},
|
||||||
|
Version: "v1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "/foo",
|
||||||
|
ValueMap: map[string]string{
|
||||||
|
"foo": "bar",
|
||||||
|
"baz": "bang",
|
||||||
|
},
|
||||||
|
Version: "v2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
request: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||||
|
Key: "/foo",
|
||||||
|
Version: "v2",
|
||||||
|
},
|
||||||
|
expValue: map[string][]byte{
|
||||||
|
"foo": []byte("bar"),
|
||||||
|
"baz": []byte("bang"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, row := range tbl {
|
||||||
|
t.Run(row.name, func(t *testing.T) {
|
||||||
|
cl, err := p.NewClient(context.Background(), &esv1alpha1.SecretStore{
|
||||||
|
Spec: esv1alpha1.SecretStoreSpec{
|
||||||
|
Provider: &esv1alpha1.SecretStoreProvider{
|
||||||
|
Fake: &esv1alpha1.FakeProvider{
|
||||||
|
Data: row.input,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil, "")
|
||||||
|
gomega.Expect(err).ToNot(gomega.HaveOccurred())
|
||||||
|
out, err := cl.GetSecretMap(context.Background(), row.request)
|
||||||
|
if row.expErr != "" {
|
||||||
|
gomega.Expect(err).To(gomega.MatchError(row.expErr))
|
||||||
|
} else {
|
||||||
|
gomega.Expect(err).ToNot(gomega.HaveOccurred())
|
||||||
|
}
|
||||||
|
gomega.Expect(out).To(gomega.Equal(row.expValue))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import (
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/alibaba"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/alibaba"
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/aws"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/aws"
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault"
|
||||||
|
_ "github.com/external-secrets/external-secrets/pkg/provider/fake"
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/gcp/secretmanager"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/gcp/secretmanager"
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/gitlab"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/gitlab"
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/ibm"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/ibm"
|
||||||
|
|
103
pkg/provider/testing/fake/fake.go
Normal file
103
pkg/provider/testing/fake/fake.go
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package fake
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ provider.Provider = &Client{}
|
||||||
|
|
||||||
|
// Client is a fake client for testing.
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a fake provider/client.
|
||||||
|
func New() *Client {
|
||||||
|
v := &Client{
|
||||||
|
GetSecretFn: func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
GetSecretMapFn: func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
v.NewFn = func(context.Context, esv1alpha1.GenericStore, client.Client, string) (provider.SecretsClient, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterAs registers the fake client in the schema.
|
||||||
|
func (v *Client) RegisterAs(provider *esv1alpha1.SecretStoreProvider) {
|
||||||
|
schema.ForceRegister(v, provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSecret implements the provider.Provider interface.
|
||||||
|
func (v *Client) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
|
||||||
|
return v.GetSecretFn(ctx, ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithGetSecret wraps secret data returned by this provider.
|
||||||
|
func (v *Client) WithGetSecret(secData []byte, err error) *Client {
|
||||||
|
v.GetSecretFn = func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
|
||||||
|
return secData, err
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSecretMap imeplements the provider.Provider interface.
|
||||||
|
func (v *Client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
||||||
|
return v.GetSecretMapFn(ctx, ref)
|
||||||
|
}
|
||||||
|
func (v *Client) Close(ctx context.Context) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
return secData, err
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithNew wraps the fake provider factory function.
|
||||||
|
func (v *Client) WithNew(f func(context.Context, esv1alpha1.GenericStore, client.Client,
|
||||||
|
string) (provider.SecretsClient, error)) *Client {
|
||||||
|
v.NewFn = f
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient returns a new fake provider.
|
||||||
|
func (v *Client) NewClient(ctx context.Context, store esv1alpha1.GenericStore, kube client.Client, namespace string) (provider.SecretsClient, error) {
|
||||||
|
c, err := v.NewFn(ctx, store, kube, namespace)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
Loading…
Reference in a new issue