Browse Source

docs: add templating v2

Signed-off-by: Moritz Johner <beller.moritz@googlemail.com>
Moritz Johner 4 years ago
parent
commit
b864f96e10

+ 2 - 2
Makefile

@@ -194,8 +194,8 @@ docs: generate ## Generate docs
 docs.publish: generate ## Generate and deploys docs
 docs.publish: generate ## Generate and deploys docs
 	$(MAKE) -C ./hack/api-docs build.publish
 	$(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
 	$(MAKE) -C ./hack/api-docs serve
 
 
 # ====================================================================================
 # ====================================================================================

+ 50 - 0
docs/guides-templating-v1.md

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

+ 67 - 20
docs/guides-templating.md

@@ -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/).
 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
 ## Examples
 
 
 You can use templates to inject your secrets into a configuration file that you mount into your pod:
 You can use templates to inject your secrets into a configuration file that you mount into your pod:
 ``` yaml
 ``` 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.
 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
 ``` yaml
-{% include 'pkcs12-template-external-secret.yaml' %}
+{% include 'pkcs12-template-v2-external-secret.yaml' %}
 ```
 ```
 
 
 ### TemplateFrom
 ### 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:
 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
 ``` yaml
-{% include 'template-from-secret.yaml' %}
+{% include 'template-v2-from-secret.yaml' %}
 ```
 ```
 
 
 ## Helper functions
 ## 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        |
 | 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.

+ 4 - 0
docs/snippets/multiline-template-external-secret.yaml

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

+ 35 - 0
docs/snippets/multiline-template-v2-external-secret.yaml

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

docs/snippets/pkcs12-template-external-secret.yaml → docs/snippets/pkcs12-template-v1-external-secret.yaml


+ 27 - 0
docs/snippets/pkcs12-template-v2-external-secret.yaml

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

docs/snippets/template-from-secret.yaml → docs/snippets/template-v1-from-secret.yaml


+ 41 - 0
docs/snippets/template-v2-from-secret.yaml

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

+ 36 - 0
docs/spec.md

@@ -1408,6 +1408,21 @@ Kubernetes core/v1.SecretType
 </tr>
 </tr>
 <tr>
 <tr>
 <td>
 <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>
 <code>metadata</code></br>
 <em>
 <em>
 <a href="#external-secrets.io/v1alpha1.ExternalSecretTemplateMetadata">
 <a href="#external-secrets.io/v1alpha1.ExternalSecretTemplateMetadata">
@@ -2666,6 +2681,27 @@ Kubernetes meta/v1.Time
 </tr>
 </tr>
 </tbody>
 </tbody>
 </table>
 </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 id="external-secrets.io/v1alpha1.TemplateFrom">TemplateFrom
 </h3>
 </h3>
 <p>
 <p>

+ 4 - 1
hack/api-docs/Dockerfile

@@ -23,4 +23,7 @@ RUN apk add -U --no-cache \
     bash \
     bash \
     gcc \
     gcc \
     diffutils \
     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"

+ 3 - 3
hack/api-docs/Makefile

@@ -53,7 +53,7 @@ build: image generate $(SOURCES)
 		--rm \
 		--rm \
 		--user $(UID):$(GID) \
 		--user $(UID):$(GID) \
 		$(MKDOCS_IMAGE) \
 		$(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
 .PHONY: build.publish
 build.publish: image generate $(SOURCES)
 build.publish: image generate $(SOURCES)
@@ -64,7 +64,7 @@ build.publish: image generate $(SOURCES)
 		--rm \
 		--rm \
 		--user $(UID):$(GID) \
 		--user $(UID):$(GID) \
 		$(MKDOCS_IMAGE) \
 		$(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
 .PHONY: generate
 generate:
 generate:
@@ -86,4 +86,4 @@ serve:
 		-p $(SERVE_BIND_ADDRESS):8000:8000 \
 		-p $(SERVE_BIND_ADDRESS):8000:8000 \
 		--rm \
 		--rm \
 		$(MKDOCS_IMAGE) \
 		$(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"

+ 3 - 1
hack/api-docs/mkdocs.yml

@@ -34,7 +34,9 @@ nav:
   - Guides:
   - Guides:
     - Introduction: guides-introduction.md
     - Introduction: guides-introduction.md
     - Getting started: guides-getting-started.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
     - Controller Classes: guides-controller-class.md
     - All keys, One secret: guides-all-keys-one-secret.md
     - All keys, One secret: guides-all-keys-one-secret.md
     - Common K8S Secret Types: guides-common-k8s-secret-types.md
     - Common K8S Secret Types: guides-common-k8s-secret-types.md

+ 15 - 15
hack/api-docs/requirements.txt

@@ -1,18 +1,18 @@
-Click==7.0
+Click==8.0.3
 htmlmin==0.1.12
 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
 mkdocs==1.2.3
 mike==1.1.2
 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