mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-14 11:57:59 +00:00
Adding docs and implementing ConversionStrategy
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>
This commit is contained in:
parent
2f23fd28ed
commit
164e8776ec
63 changed files with 276 additions and 106 deletions
|
@ -141,8 +141,19 @@ type ExternalSecretDataRemoteRef struct {
|
|||
// +optional
|
||||
// Used to select a specific property of the Provider value (if a map), if supported
|
||||
Property string `json:"property,omitempty"`
|
||||
// +optional
|
||||
// Used to define a conversion Strategy
|
||||
// +kubebuilder:default="Default"
|
||||
ConversionStrategy ExternalSecretConversionStrategy `json:"conversionStrategy,omitempty"`
|
||||
}
|
||||
|
||||
type ExternalSecretConversionStrategy string
|
||||
|
||||
const (
|
||||
ExternalSecretConversionDefault ExternalSecretConversionStrategy = "Default"
|
||||
ExternalSecretConversionUnicode ExternalSecretConversionStrategy = "Unicode"
|
||||
)
|
||||
|
||||
// ExternalSecretSpec defines the desired state of ExternalSecret.
|
||||
type ExternalSecretSpec struct {
|
||||
SecretStoreRef SecretStoreRef `json:"secretStoreRef"`
|
||||
|
|
|
@ -159,8 +159,20 @@ type ExternalSecretDataRemoteRef struct {
|
|||
// +optional
|
||||
// Used to select a specific property of the Provider value (if a map), if supported
|
||||
Property string `json:"property,omitempty"`
|
||||
|
||||
// +optional
|
||||
// Used to define a conversion Strategy
|
||||
// +kubebuilder:default="Default"
|
||||
ConversionStrategy ExternalSecretConversionStrategy `json:"conversionStrategy,omitempty"`
|
||||
}
|
||||
|
||||
type ExternalSecretConversionStrategy string
|
||||
|
||||
const (
|
||||
ExternalSecretConversionDefault ExternalSecretConversionStrategy = "Default"
|
||||
ExternalSecretConversionUnicode ExternalSecretConversionStrategy = "Unicode"
|
||||
)
|
||||
|
||||
// +kubebuilder:validation:MinProperties=1
|
||||
// +kubebuilder:validation:MaxProperties=1
|
||||
type ExternalSecretDataFromRemoteRef struct {
|
||||
|
@ -172,8 +184,6 @@ type ExternalSecretDataFromRemoteRef struct {
|
|||
Find *ExternalSecretFind `json:"find,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:validation:MinProperties=1
|
||||
// +kubebuilder:validation:MaxProperties=1
|
||||
type ExternalSecretFind struct {
|
||||
// A root path to start the find operations.
|
||||
// +optional
|
||||
|
@ -185,6 +195,10 @@ type ExternalSecretFind struct {
|
|||
// Find secrets based on tags.
|
||||
// +optional
|
||||
Tags map[string]string `json:"tags,omitempty"`
|
||||
// +optional
|
||||
// Used to define a conversion Strategy
|
||||
// +kubebuilder:default="Default"
|
||||
ConversionStrategy ExternalSecretConversionStrategy `json:"conversionStrategy,omitempty"`
|
||||
}
|
||||
|
||||
type FindName struct {
|
||||
|
|
|
@ -59,6 +59,10 @@ spec:
|
|||
description: ExternalSecretDataRemoteRef defines Provider data
|
||||
location.
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
|
@ -87,6 +91,10 @@ spec:
|
|||
items:
|
||||
description: ExternalSecretDataRemoteRef defines Provider data location.
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
|
@ -294,6 +302,10 @@ spec:
|
|||
description: ExternalSecretDataRemoteRef defines Provider data
|
||||
location.
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
|
@ -327,6 +339,10 @@ spec:
|
|||
description: Used to extract multiple key/value pairs from one
|
||||
secret
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
|
@ -343,9 +359,11 @@ spec:
|
|||
type: object
|
||||
find:
|
||||
description: Used to find secrets based on tags or regular expressions
|
||||
maxProperties: 1
|
||||
minProperties: 1
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
name:
|
||||
description: Finds secrets based on the name.
|
||||
properties:
|
||||
|
|
|
@ -2019,6 +2019,10 @@ spec:
|
|||
remoteRef:
|
||||
description: ExternalSecretDataRemoteRef defines Provider data location.
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
|
@ -2043,6 +2047,10 @@ spec:
|
|||
items:
|
||||
description: ExternalSecretDataRemoteRef defines Provider data location.
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
|
@ -2226,6 +2234,10 @@ spec:
|
|||
remoteRef:
|
||||
description: ExternalSecretDataRemoteRef defines Provider data location.
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
|
@ -2254,6 +2266,10 @@ spec:
|
|||
extract:
|
||||
description: Used to extract multiple key/value pairs from one secret
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
|
@ -2268,9 +2284,11 @@ spec:
|
|||
type: object
|
||||
find:
|
||||
description: Used to find secrets based on tags or regular expressions
|
||||
maxProperties: 1
|
||||
minProperties: 1
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
name:
|
||||
description: Finds secrets based on the name.
|
||||
properties:
|
||||
|
|
|
@ -11,7 +11,7 @@ management. Vault itself implements lots of different secret engines, as of now
|
|||
First, create a SecretStore with a vault backend. For the sake of simplicity we'll use a static token `root`:
|
||||
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: vault-backend
|
||||
|
@ -46,7 +46,7 @@ vault kv put secret/foo my-value=s3cr3t
|
|||
Now create a ExternalSecret that uses the above SecretStore:
|
||||
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: vault-example
|
||||
|
@ -76,7 +76,7 @@ data:
|
|||
You can fetch all key/value pairs for a given path If you leave the `remoteRef.property` empty. This returns the json-encoded secret value for that path.
|
||||
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: vault-example
|
||||
|
@ -105,7 +105,7 @@ Given the following secret - assume its path is `/dev/config`:
|
|||
|
||||
You can set the `remoteRef.property` to point to the nested key using a [gjson](https://github.com/tidwall/gjson) expression.
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: vault-example
|
||||
|
@ -141,15 +141,16 @@ Given the following secret - assume its path is `/dev/config`:
|
|||
|
||||
You can set the `remoteRef.property` to point to the nested key using a [gjson](https://github.com/tidwall/gjson) expression.
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: vault-example
|
||||
spec:
|
||||
# ...
|
||||
dataFrom:
|
||||
- key: /dev/config
|
||||
property: foo.nested
|
||||
- extract:
|
||||
key: /dev/config
|
||||
property: foo.nested
|
||||
```
|
||||
|
||||
That results in a secret with these values:
|
||||
|
@ -158,6 +159,80 @@ bar=mysecret
|
|||
baz=bang
|
||||
```
|
||||
|
||||
#### Getting multiple secrets
|
||||
|
||||
You can extract multiple secrets from Hashicorp vault by using `dataFrom.Find`
|
||||
|
||||
Currently, `dataFrom.Find` allows users to fetch secret names that match a given regexp pattern, or fetch secrets whose `custom_metadata` tags match a predefined set.
|
||||
|
||||
Given the following secret - assume its path is `/dev/config`:
|
||||
```json
|
||||
{
|
||||
"foo": {
|
||||
"nested": {
|
||||
"bar": "mysecret",
|
||||
"baz": "bang"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Also consider the following secret has the following `custom_metadata`:
|
||||
```json
|
||||
{
|
||||
"environment": "dev",
|
||||
"component": "app-1"
|
||||
}
|
||||
```
|
||||
|
||||
It is possible to find this secret by all the following possibilities:
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: vault-example
|
||||
spec:
|
||||
# ...
|
||||
dataFrom:
|
||||
- find: #will return every secret with 'dev' in it (including paths)
|
||||
name:
|
||||
regexp: dev
|
||||
- find: #will return every secret matching environment:dev tags from dev/ folder and beyond
|
||||
tags:
|
||||
environment: dev
|
||||
```
|
||||
will generate a secret with:
|
||||
```json
|
||||
{
|
||||
"dev_config":"{\"foo\": {\"nested\": {\"bar\": \"mysecret\",\"baz\": \"bang\"}}}"
|
||||
}
|
||||
```
|
||||
|
||||
Currently, `Find` operations are recursive throughout a given vault folder, starting on `provider.Path` definition. It is recommended to narrow down the scope of search by setting a `find.path` variable. This is also useful to automatically reduce the resulting secret key names:
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: vault-example
|
||||
spec:
|
||||
# ...
|
||||
dataFrom:
|
||||
- find: #will return every secret from dev/ folder
|
||||
path: dev
|
||||
name:
|
||||
regexp: ".*"
|
||||
- find: #will return every secret matching environment:dev tags from dev/ folder
|
||||
path: dev
|
||||
tags:
|
||||
environment: dev
|
||||
```
|
||||
Will generate a secret with:
|
||||
```json
|
||||
{
|
||||
"config":"{\"foo\": {\"nested\": {\"bar\": \"mysecret\",\"baz\": \"bang\"}}}"
|
||||
}
|
||||
|
||||
```
|
||||
### Authentication
|
||||
|
||||
We support five different modes for authentication:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: akeyless-external-secret-example-json
|
||||
|
@ -15,4 +15,5 @@ spec:
|
|||
|
||||
# for json formatted secrets: each key in the json will be used as the secret key in the SECRET k8s target object
|
||||
dataFrom:
|
||||
- key: secret-name # Full path of the secret on Akeyless
|
||||
- extract:
|
||||
key: secret-name # Full path of the secret on Akeyless
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: akeyless-external-secret-example
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: akeyless-secret-store
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: anchore-access-credentials
|
||||
|
@ -12,4 +12,5 @@ spec:
|
|||
target:
|
||||
name: anchore-access-credentials
|
||||
dataFrom:
|
||||
- key: service/anchore-engine/engineAccess
|
||||
- extract:
|
||||
key: service/anchore-engine/engineAccess
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: github-ssh-access
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: sonarqube-api-token
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: harbor-chart-robot
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: secretstore-sample
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: secretstore-sample
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example-external-secret
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: example-secret-store
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: example-secret-store
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example
|
||||
|
@ -17,4 +17,5 @@ spec:
|
|||
version: provider-key-version
|
||||
property: provider-key-property
|
||||
dataFrom:
|
||||
- key: remote-key-in-the-provider
|
||||
- extract:
|
||||
key: remote-key-in-the-provider
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: secretstore-sample
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: controller-custom-example
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example
|
||||
|
@ -15,4 +15,5 @@ spec:
|
|||
key: /foo/bar
|
||||
version: v1
|
||||
dataFrom:
|
||||
- key: /foo/baz
|
||||
- extract:
|
||||
key: /foo/baz
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ClusterSecretStore
|
||||
metadata:
|
||||
name: fake
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ClusterSecretStore
|
||||
metadata:
|
||||
name: example
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: "hello-world"
|
||||
|
@ -73,9 +73,18 @@ spec:
|
|||
# Used to fetch all properties from the Provider key
|
||||
# If multiple dataFrom are specified, secrets are merged in the specified order
|
||||
dataFrom:
|
||||
- key: provider-key
|
||||
version: provider-key-version
|
||||
property: provider-key-property
|
||||
- extract:
|
||||
key: provider-key
|
||||
version: provider-key-version
|
||||
property: provider-key-property
|
||||
conversionStrategy: Default
|
||||
- find:
|
||||
path: path-to-filter
|
||||
name:
|
||||
regexp: ".*foobar.*"
|
||||
tags:
|
||||
foo: bar
|
||||
conversionStrategy: Unicode
|
||||
|
||||
status:
|
||||
# refreshTime is the time and date the external secret was fetched and
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: example
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example
|
||||
|
@ -11,4 +11,5 @@ spec:
|
|||
name: secret-to-be-created # name of the k8s Secret to be created
|
||||
creationPolicy: Owner
|
||||
dataFrom:
|
||||
- key: all-keys-example-secret # name of the GCPSM secret
|
||||
- extract:
|
||||
key: all-keys-example-secret # name of the GCPSM secret
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: dk-cfg-example
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: example
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: example
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: ssh-auth-example
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: template-tls-example
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ClusterSecretStore
|
||||
metadata:
|
||||
name: example
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: gitlab-external-secret-example
|
||||
|
@ -15,4 +15,5 @@ spec:
|
|||
|
||||
# each secret name in the KV will be used as the secret key in the SECRET k8s target object
|
||||
dataFrom:
|
||||
- key: "myJsonVariable" # Key of the variable on Gitlab
|
||||
- extract:
|
||||
key: "myJsonVariable" # Key of the variable on Gitlab
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: gitlab-external-secret-example
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: gitlab-secret-store
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ClusterSecretStore
|
||||
metadata:
|
||||
name: vault-backend-global
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: ibm-sample
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: external-secret-sample
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: secretstore-sample
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: template
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: template
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: template
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example
|
||||
|
@ -11,4 +11,5 @@ spec:
|
|||
name: secret-to-be-created # Name for the secret on the cluster
|
||||
creationPolicy: Owner
|
||||
dataFrom:
|
||||
- key: the-secret-name
|
||||
- extract:
|
||||
key: the-secret-name
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: example-instance-principal
|
||||
|
@ -10,7 +10,7 @@ spec:
|
|||
|
||||
---
|
||||
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: example-auth
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: template
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: template
|
||||
|
|
|
@ -13,7 +13,7 @@ You can attach a role to the pod using [IRSA](https://docs.aws.amazon.com/eks/la
|
|||
Based on the Pod's identity you can do a `sts:assumeRole` before fetching the secrets to limit access to certain keys in your provider. This is optional.
|
||||
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: team-b-store
|
||||
|
@ -33,7 +33,7 @@ spec:
|
|||
You can store Access Key ID & Secret Access Key in a `Kind=Secret` and reference it from a SecretStore.
|
||||
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: team-b-store
|
||||
|
@ -78,7 +78,7 @@ metadata:
|
|||
Reference the service account from above in the Secret Store:
|
||||
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: secretstore-sample
|
||||
|
|
|
@ -14,7 +14,7 @@ data:
|
|||
password: "{{ .password | toString }}" # <-- convert []byte to string
|
||||
user: "{{ .user | toString }}" # <-- convert []byte to string
|
||||
---
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: my-template-example
|
||||
|
|
|
@ -14,7 +14,7 @@ data:
|
|||
password: "{{ .password }}"
|
||||
user: "{{ .user }}"
|
||||
---
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: my-template-example
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: anchore-access-credentials
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: vault-backend
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: github-ssh-access
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: harbor-chart-robot
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% raw %}
|
||||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: sonarqube-api-token
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: vault-backend
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: vault-backend
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: vault-backend
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: external-secrets.io/v1alpha1
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: vault-backend
|
||||
|
|
|
@ -46,6 +46,8 @@ const (
|
|||
requeueAfter = time.Second * 30
|
||||
|
||||
errGetES = "could not get ExternalSecret"
|
||||
errConvert = "could not apply conversion strategy to keys: %v"
|
||||
errFindSecretKey = "could not find secret %v: %v"
|
||||
errUpdateSecret = "could not update Secret"
|
||||
errPatchStatus = "unable to patch status"
|
||||
errGetSecretStore = "could not get SecretStore %q, %w"
|
||||
|
@ -400,13 +402,21 @@ func (r *Reconciler) getProviderSecretData(ctx context.Context, providerClient e
|
|||
if remoteRef.Find != nil {
|
||||
secretMap, err = providerClient.GetAllSecrets(ctx, *remoteRef.Find)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errGetSecretKey, remoteRef.Extract.Key, externalSecret.Name, err)
|
||||
return nil, fmt.Errorf(errFindSecretKey, externalSecret.Name, err)
|
||||
}
|
||||
secretMap, err = utils.ConvertKeys(remoteRef.Find.ConversionStrategy, secretMap)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errConvert, err)
|
||||
}
|
||||
} else if remoteRef.Extract != nil {
|
||||
secretMap, err = providerClient.GetSecretMap(ctx, *remoteRef.Extract)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errGetSecretKey, remoteRef.Extract.Key, externalSecret.Name, err)
|
||||
}
|
||||
secretMap, err = utils.ConvertKeys(remoteRef.Extract.ConversionStrategy, secretMap)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errConvert, err)
|
||||
}
|
||||
}
|
||||
|
||||
providerData = utils.MergeByteMap(providerData, secretMap)
|
||||
|
|
|
@ -276,11 +276,10 @@ func (v *client) findSecretsFromTags(ctx context.Context, candidates []string, t
|
|||
if removeFromName != "" {
|
||||
name = strings.TrimPrefix(name, removeFromName)
|
||||
}
|
||||
newName := utils.ConvertName(name)
|
||||
if _, exists := secrets[newName]; exists {
|
||||
return nil, fmt.Errorf(errDuplicateSecret, newName)
|
||||
if _, exists := secrets[name]; exists {
|
||||
return nil, fmt.Errorf(errDuplicateSecret, name)
|
||||
}
|
||||
secrets[newName] = secret
|
||||
secrets[name] = secret
|
||||
}
|
||||
}
|
||||
return secrets, nil
|
||||
|
@ -301,11 +300,10 @@ func (v *client) findSecretsFromName(ctx context.Context, candidates []string, r
|
|||
if removeFromName != "" {
|
||||
name = strings.TrimPrefix(name, removeFromName)
|
||||
}
|
||||
newName := utils.ConvertName(name)
|
||||
if _, exists := secrets[newName]; exists {
|
||||
return nil, fmt.Errorf(errDuplicateSecret, newName)
|
||||
if _, exists := secrets[name]; exists {
|
||||
return nil, fmt.Errorf(errDuplicateSecret, name)
|
||||
}
|
||||
secrets[newName] = secret
|
||||
secrets[name] = secret
|
||||
}
|
||||
}
|
||||
return secrets, nil
|
||||
|
|
|
@ -21,7 +21,6 @@ import (
|
|||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"unicode"
|
||||
|
||||
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
|
||||
|
@ -36,23 +35,34 @@ func MergeByteMap(dst, src map[string][]byte) map[string][]byte {
|
|||
return dst
|
||||
}
|
||||
|
||||
// ConvertName converts a string into a secret-key compatible string.
|
||||
// Replaces any non-alphanumeric characters with its unicode code.
|
||||
func ConvertName(in string) string {
|
||||
out := make([]string, len(in))
|
||||
rs := []rune(in)
|
||||
for k, r := range rs {
|
||||
if !unicode.IsNumber(r) &&
|
||||
!unicode.IsLetter(r) &&
|
||||
r != '-' &&
|
||||
r != '.' &&
|
||||
r != '_' {
|
||||
out[k] = fmt.Sprintf("_U%04x_", r)
|
||||
} else {
|
||||
out[k] = string(r)
|
||||
// ConvertKeys converts a secret map into a valid key.
|
||||
// Replaces any non-alphanumeric characters depending on convert strategy.
|
||||
func ConvertKeys(strategy esv1beta1.ExternalSecretConversionStrategy, in map[string][]byte) (map[string][]byte, error) {
|
||||
out := make(map[string][]byte)
|
||||
for k, v := range in {
|
||||
rs := []rune(k)
|
||||
newName := make([]string, len(rs))
|
||||
for rk, rv := range rs {
|
||||
if !unicode.IsNumber(rv) &&
|
||||
!unicode.IsLetter(rv) &&
|
||||
rv != '-' &&
|
||||
rv != '.' &&
|
||||
rv != '_' {
|
||||
switch strategy {
|
||||
case esv1beta1.ExternalSecretConversionDefault:
|
||||
newName[rk] = "_"
|
||||
case esv1beta1.ExternalSecretConversionUnicode:
|
||||
newName[rk] = fmt.Sprintf("_U%04x_", rv)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown conversion strategy: %s", strategy)
|
||||
}
|
||||
} else {
|
||||
newName[rk] = string(rv)
|
||||
}
|
||||
}
|
||||
out[strings.Join(newName, "")] = v
|
||||
}
|
||||
return strings.Join(out, "")
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// MergeStringMap performs a deep clone from src to dest.
|
||||
|
|
Loading…
Reference in a new issue