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

docs: add templating v2

Signed-off-by: Moritz Johner <beller.moritz@googlemail.com>
This commit is contained in:
Moritz Johner 2022-02-08 11:00:10 +01:00
parent a627e82639
commit b864f96e10
14 changed files with 287 additions and 42 deletions

View file

@ -194,8 +194,8 @@ docs: generate ## Generate docs
docs.publish: generate ## Generate and deploys docs
$(MAKE) -C ./hack/api-docs build.publish
.PHONY: serve-docs
serve-docs: ## Serve docs
.PHONY: docs.serve
docs.serve: ## Serve docs
$(MAKE) -C ./hack/api-docs serve
# ====================================================================================

View file

@ -0,0 +1,50 @@
# Advanced Templating v1
!!! warning
Templating Engine v1 is **deprecated** and will be removed in the future. Please migrate to engine v2 and take a look at our [upgrade guide](guides-templating.md#migrating-from-v1) for changes.
With External Secrets Operator you can transform the data from the external secret provider before it is stored as `Kind=Secret`. You can do this with the `Spec.Target.Template`. Each data value is interpreted as a [golang template](https://golang.org/pkg/text/template/).
## Examples
You can use templates to inject your secrets into a configuration file that you mount into your pod:
``` yaml
{% include 'multiline-template-v1-external-secret.yaml' %}
```
You can also use pre-defined functions to extract data from your secrets. Here: extract key/cert from a pkcs12 archive and store it as PEM.
``` yaml
{% include 'pkcs12-template-v1-external-secret.yaml' %}
```
### TemplateFrom
You do not have to define your templates inline in an ExternalSecret but you can pull `ConfigMaps` or other Secrets that contain a template. Consider the following example:
``` yaml
{% include 'template-v1-from-secret.yaml' %}
```
## Helper functions
We provide a bunch of convenience functions that help you transform your secrets. A secret value is a `[]byte`.
| Function | Description | Input | Output |
| -------------- | -------------------------------------------------------------------------- | -------------------------------- | ------------- |
| pkcs12key | extracts the private key from a pkcs12 archive | `[]byte` | `[]byte` |
| pkcs12keyPass | extracts the private key from a pkcs12 archive using the provided password | password `string`, data `[]byte` | `[]byte` |
| pkcs12cert | extracts the certificate from a pkcs12 archive | `[]byte` | `[]byte` |
| pkcs12certPass | extracts the certificate from a pkcs12 archive using the provided password | password `string`, data `[]byte` | `[]byte` |
| pemPrivateKey | PEM encodes the provided bytes as private key | `[]byte` | `string` |
| pemCertificate | PEM encodes the provided bytes as certificate | `[]byte` | `string` |
| jwkPublicKeyPem | takes an json-serialized JWK as `[]byte` and returns an PEM block of type `PUBLIC KEY` that contains the public key ([see here](https://golang.org/pkg/crypto/x509/#MarshalPKIXPublicKey)) for details | `[]byte` | `string` |
| jwkPrivateKeyPem | takes an json-serialized JWK as `[]byte` and returns an PEM block of type `PRIVATE KEY` that contains the private key in PKCS #8 format ([see here](https://golang.org/pkg/crypto/x509/#MarshalPKCS8PrivateKey)) for details | `[]byte` | `string` |
| base64decode | decodes the provided bytes as base64 | `[]byte` | `[]byte` |
| base64encode | encodes the provided bytes as base64 | `[]byte` | `[]byte` |
| fromJSON | parses the bytes as JSON so you can access individual properties | `[]byte` | `interface{}` |
| toJSON | encodes the provided object as json string | `interface{}` | `string` |
| toString | converts bytes to string | `[]byte` | `string` |
| toBytes | converts string to bytes | `string` | `[]byte` |
| upper | converts all characters to their upper case | `string` | `string` |
| lower | converts all character to their lower case | `string` | `string` |

View file

@ -1,15 +1,17 @@
# Advanced Templating v2
With External Secrets Operator you can transform the data from the external secret provider before it is stored as `Kind=Secret`. You can do this with the `Spec.Target.Template`. Each data value is interpreted as a [golang template](https://golang.org/pkg/text/template/).
## Examples
You can use templates to inject your secrets into a configuration file that you mount into your pod:
``` yaml
{% include 'multiline-template-external-secret.yaml' %}
{% include 'multiline-template-v2-external-secret.yaml' %}
```
You can also use pre-defined functions to extract data from your secrets. Here: extract key/cert from a pkcs12 archive and store it as PEM.
``` yaml
{% include 'pkcs12-template-external-secret.yaml' %}
{% include 'pkcs12-template-v2-external-secret.yaml' %}
```
### TemplateFrom
@ -17,27 +19,72 @@ You can also use pre-defined functions to extract data from your secrets. Here:
You do not have to define your templates inline in an ExternalSecret but you can pull `ConfigMaps` or other Secrets that contain a template. Consider the following example:
``` yaml
{% include 'template-from-secret.yaml' %}
{% include 'template-v2-from-secret.yaml' %}
```
## Helper functions
We provide a bunch of convenience functions that help you transform your secrets. A secret value is a `[]byte`.
!!! info inline end
Note: we removed `env` and `expandenv` from sprig functions for security reasons.
We provide a couple of convenience functions that help you transform your secrets. This is useful when dealing with pkcs12 or jwk encoded secrets.
In addition to that you can use over 200+ [sprig functions](http://masterminds.github.io/sprig/). If you feel a function is missing or might be valuable feel free to open an issue and submit a [pull request](contributing-process.md#submitting-a-pull-request).
<br/>
| Function | Description | Input | Output |
| -------------- | -------------------------------------------------------------------------- | -------------------------------- | ------------- |
| pkcs12key | extracts the private key from a pkcs12 archive | `[]byte` | `[]byte` |
| pkcs12keyPass | extracts the private key from a pkcs12 archive using the provided password | password `string`, data `[]byte` | `[]byte` |
| pkcs12cert | extracts the certificate from a pkcs12 archive | `[]byte` | `[]byte` |
| pkcs12certPass | extracts the certificate from a pkcs12 archive using the provided password | password `string`, data `[]byte` | `[]byte` |
| pemPrivateKey | PEM encodes the provided bytes as private key | `[]byte` | `string` |
| pemCertificate | PEM encodes the provided bytes as certificate | `[]byte` | `string` |
| jwkPublicKeyPem | takes an json-serialized JWK as `[]byte` and returns an PEM block of type `PUBLIC KEY` that contains the public key ([see here](https://golang.org/pkg/crypto/x509/#MarshalPKIXPublicKey)) for details | `[]byte` | `string` |
| jwkPrivateKeyPem | takes an json-serialized JWK as `[]byte` and returns an PEM block of type `PRIVATE KEY` that contains the private key in PKCS #8 format ([see here](https://golang.org/pkg/crypto/x509/#MarshalPKCS8PrivateKey)) for details | `[]byte` | `string` |
| base64decode | decodes the provided bytes as base64 | `[]byte` | `[]byte` |
| base64encode | encodes the provided bytes as base64 | `[]byte` | `[]byte` |
| fromJSON | parses the bytes as JSON so you can access individual properties | `[]byte` | `interface{}` |
| toJSON | encodes the provided object as json string | `interface{}` | `string` |
| toString | converts bytes to string | `[]byte` | `string` |
| toBytes | converts string to bytes | `string` | `[]byte` |
| upper | converts all characters to their upper case | `string` | `string` |
| lower | converts all character to their lower case | `string` | `string` |
| pkcs12key | extracts the private key from a pkcs12 archive | `string` | `string` |
| pkcs12keyPass | extracts the private key from a pkcs12 archive using the provided password | password `string`, data `string` | `string` |
| pkcs12cert | extracts the certificate from a pkcs12 archive | `string` | `string` |
| pkcs12certPass | extracts the certificate from a pkcs12 archive using the provided password | password `string`, data `string` | `string` |
| pemPrivateKey | PEM encodes the provided bytes as private key | `string` | `string` |
| pemCertificate | PEM encodes the provided bytes as certificate | `string` | `string` |
| jwkPublicKeyPem | takes an json-serialized JWK as `string` and returns an PEM block of type `PUBLIC KEY` that contains the public key ([see here](https://golang.org/pkg/crypto/x509/#MarshalPKIXPublicKey)) for details | `string` | `string` |
| jwkPrivateKeyPem | takes an json-serialized JWK as `string` and returns an PEM block of type `PRIVATE KEY` that contains the private key in PKCS #8 format ([see here](https://golang.org/pkg/crypto/x509/#MarshalPKCS8PrivateKey)) for details | `string` | `string` |
## Migrating from v1
You have to opt-in to use the new engine version by specifying `template.engineVersion=v2`:
```yaml
apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
metadata:
name: secret
spec:
# ...
target:
template:
engineVersion: v2
# ...
```
The biggest change was that basically all function parameter types were changed from accepting/returning `[]byte` to `string`. This is relevant for you because now you don't need to specify `toString` all the time at the end of a template pipeline.
```yaml
{% raw %}
apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
# ...
spec:
target:
template:
engineVersion: v2
data:
# this used to be {{ .foobar | toString }}
egg: "new: {{ .foobar }}"
#
mycert: "{{ .mysecret | pkcs12cert | pemCertificate }}"
{% endraw %}
```
##### Functions removed/replaced
* `base64encode` was renamed to `b64dec`.
* `base64decode` was renamed to `b64dec`. Any errors that occurr during decoding are silenced.
* `fromJSON` was renamed to `toJson`. Any errors that occurr during unmarshalling are silenced.
* `toJSON` was renamed to `toJson`. Any errors that occurr during marshalling are silenced.
* `toString` implementation was replaced by the `sprig` implementation and should be api-compatible.
* `toBytes` was removed.

View file

@ -10,6 +10,10 @@ spec:
kind: SecretStore
target:
name: secret-to-be-created
# v1 is the default version
engineVersion: v1
# this is how the Kind=Secret will look like
template:
type: kubernetes.io/tls

View file

@ -0,0 +1,35 @@
{% raw %}
apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
metadata:
name: template
spec:
refreshInterval: 1h
secretStoreRef:
name: secretstore-sample
kind: SecretStore
target:
name: secret-to-be-created
# this is how the Kind=Secret will look like
template:
type: kubernetes.io/tls
engineVersion: v2
data:
# multiline string
config: |
datasources:
- name: Graphite
type: graphite
access: proxy
url: http://localhost:8080
password: "{{ .password }}"
user: "{{ .user }}"
data:
- secretKey: user
remoteRef:
key: /grafana/user
- secretKey: password
remoteRef:
key: /grafana/password
{% endraw %}

View file

@ -0,0 +1,27 @@
{% raw %}
apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
metadata:
name: template
spec:
refreshInterval: 1h
secretStoreRef:
name: secretstore-sample
kind: SecretStore
target:
name: secret-to-be-created
# this is how the Kind=Secret will look like
template:
type: kubernetes.io/tls
engineVersion: v2
data:
tls.crt: "{{ .mysecret | pkcs12cert | pemCertificate }}"
tls.key: "{{ .mysecret | pkcs12key | pemPrivateKey }}"
data:
# this is a pkcs12 archive that contains
# a cert and a private key
- secretKey: mysecret
remoteRef:
key: example
{% endraw %}

View file

@ -0,0 +1,41 @@
{% raw %}
# define your template in a config map
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-config-tpl
data:
config.yaml: |
datasources:
- name: Graphite
type: graphite
access: proxy
url: http://localhost:8080
password: "{{ .password }}"
user: "{{ .user }}"
---
apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
metadata:
name: my-template-example
spec:
# ...
target:
name: secret-to-be-created
template:
engineVersion: v2
templateFrom:
- configMap:
# name of the configmap to pull in
name: grafana-config-tpl
# here you define the keys that should be used as template
items:
- key: config.yaml
data:
- secretKey: user
remoteRef:
key: /grafana/user
- secretKey: password
remoteRef:
key: /grafana/password
{% endraw %}

View file

@ -1408,6 +1408,21 @@ Kubernetes core/v1.SecretType
</tr>
<tr>
<td>
<code>engineVersion</code></br>
<em>
<a href="#external-secrets.io/v1alpha1.TemplateEngineVersion">
TemplateEngineVersion
</a>
</em>
</td>
<td>
<p>EngineVersion specifies the template engine version
that should be used to compile/execute the
template specified in .data and .templateFrom[].</p>
</td>
</tr>
<tr>
<td>
<code>metadata</code></br>
<em>
<a href="#external-secrets.io/v1alpha1.ExternalSecretTemplateMetadata">
@ -2666,6 +2681,27 @@ Kubernetes meta/v1.Time
</tr>
</tbody>
</table>
<h3 id="external-secrets.io/v1alpha1.TemplateEngineVersion">TemplateEngineVersion
(<code>string</code> alias)</p></h3>
<p>
(<em>Appears on:</em>
<a href="#external-secrets.io/v1alpha1.ExternalSecretTemplate">ExternalSecretTemplate</a>)
</p>
<p>
</p>
<table>
<thead>
<tr>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr><td><p>&#34;v1&#34;</p></td>
<td></td>
</tr><tr><td><p>&#34;v2&#34;</p></td>
<td></td>
</tr></tbody>
</table>
<h3 id="external-secrets.io/v1alpha1.TemplateFrom">TemplateFrom
</h3>
<p>

View file

@ -23,4 +23,7 @@ RUN apk add -U --no-cache \
bash \
gcc \
diffutils \
&& pip3 install -r /requirements.txt
&& pip3 install -r /requirements.txt
RUN git config --global user.email "docs@external-secrets.io"
RUN git config --global user.name "Docs"

View file

@ -53,7 +53,7 @@ build: image generate $(SOURCES)
--rm \
--user $(UID):$(GID) \
$(MKDOCS_IMAGE) \
/bin/bash -c "cd /repo && git config user.email "docs@external-secrets.io" && git config user.name "Docs" && $(MIKE) deploy --update-aliases -F hack/api-docs/mkdocs.yml $(DOCS_VERSION) $(DOCS_ALIAS);"
/bin/bash -c "cd /repo && $(MIKE) deploy --ignore --update-aliases -F hack/api-docs/mkdocs.yml $(DOCS_VERSION) $(DOCS_ALIAS);"
.PHONY: build.publish
build.publish: image generate $(SOURCES)
@ -64,7 +64,7 @@ build.publish: image generate $(SOURCES)
--rm \
--user $(UID):$(GID) \
$(MKDOCS_IMAGE) \
/bin/bash -c "cd /repo && git config user.email "docs@external-secrets.io" && git config user.name "Docs" && $(MIKE) deploy --update-aliases -p -F hack/api-docs/mkdocs.yml $(DOCS_VERSION) $(DOCS_ALIAS);"
/bin/bash -c "cd /repo && $(MIKE) deploy --update-aliases -p -F hack/api-docs/mkdocs.yml $(DOCS_VERSION) $(DOCS_ALIAS);"
.PHONY: generate
generate:
@ -86,4 +86,4 @@ serve:
-p $(SERVE_BIND_ADDRESS):8000:8000 \
--rm \
$(MKDOCS_IMAGE) \
/bin/bash -c "cd /repo && $(MIKE) serve -F hack/api-docs/mkdocs.yml -a 0.0.0.0:8000"
/bin/bash -c "cd /repo && mkdocs serve -f hack/api-docs/mkdocs.yml -a 0.0.0.0:8000"

View file

@ -34,7 +34,9 @@ nav:
- Guides:
- Introduction: guides-introduction.md
- Getting started: guides-getting-started.md
- Advanced Templating: guides-templating.md
- Advanced Templating:
v2: guides-templating.md
v1: guides-templating-v1.md
- Controller Classes: guides-controller-class.md
- All keys, One secret: guides-all-keys-one-secret.md
- Common K8S Secret Types: guides-common-k8s-secret-types.md

View file

@ -1,18 +1,18 @@
Click==7.0
Click==8.0.3
htmlmin==0.1.12
Jinja2==2.11.1
jsmin==2.2.2
livereload==2.6.1
Markdown==3.2.1
MarkupSafe==1.1.1
Jinja2==3.0.3
jsmin==3.0.1
livereload==2.6.3
Markdown==3.3.6
MarkupSafe==2.0.1
mkdocs==1.2.3
mike==1.1.2
mkdocs-material==8.1.9
mkdocs-minify-plugin==0.2.1
pep562==1.0
Pygments==2.10.0
pymdown-extensions==9.0
PyYAML==5.3
six==1.14.0
tornado==6.0.3
mkdocs-macros-plugin==0.4.18
mkdocs-material==8.1.10
mkdocs-minify-plugin==0.5.0
pep562==1.1
Pygments==2.11.2
pymdown-extensions==9.1
PyYAML==6.0
six==1.16.0
tornado==6.1
mkdocs-macros-plugin==0.6.4