Skip to content

Latest commit

 

History

History
224 lines (180 loc) · 9.95 KB

Templating.md

File metadata and controls

224 lines (180 loc) · 9.95 KB

Templating

Landscaper uses templating to dynamically generate configurations based on a given data binding for various purposes. An example is the generation of deployitem manifests based on the imports of a blueprint. The Landscaper supports multiple template engines. Depending on the purpose, dedicated value bindings are provided as input for the templating. Templating is executed in so-called 'executions', defining the context for the templating. Landscaper uses executions for:

For each of these purposes, a list of executions can be specified. Every execution can use a different template engine. The results of all specified executions with the same purpose will be merged.

For detailed information of blueprints see the Blueprint Docs.

Template Execution

Landscaper uses templating for various purposes, most prominently in the blueprint (e.g. for deployitem and export generation). The dedicated section in the respective manifests is always a list of template execution configurations. Each execution is defined by a set of attributes:

  • name string The name is used for providing error messages during the templating execution. It is also used as an identifier for the state of the execution.

  • type string The type specifies which template engine should be used. Currently supported types are GoTemplate and Spiff.

  • file string [optional] If this property is set, the template is read from the specified file of the blueprint file structure. Exactly one of file and template has to be specified.

  • template template [optional] If this property is set, the template is read from the given inline data, according to the specification of the specified template engine type. Exactly one of file and template has to be specified.

The the rendered output of the templating must always be a YAML document. The document is expected to be a map. The structure is the same, independent of which template engine is used. The expected result is always read from a dedicated key, depending on the execution (e.g. deployItems for deployitem executions).

Example

deployExecutions:
- name: my-spiff-template
  type: Spiff
  template:
    deployItems:
    - name: my-first-deploy-item
      type: landscaper.gardener.cloud/mock
      config: ...
- name: my-go-template
  type: GoTemplate
  template: |
    deployitems:
    - name: my-second-deploy-item
      type: landscaper.gardener.cloud/mock
      config: ...

Filesystem

The blueprint's filesystem structure is accessible for the template engines as root file system.

Depending on what is being rendered, there is more data available during the templating, such as imports, etc.. The available bindings are described in the docs belonging to the resource the templates are part of, e.g. here for the templates in blueprints.

Example

  • Filesystem
    my-blueprint
    ├── data
    │   ├── template
    │   └── config
    └── blueprint.yaml
    
  • Execution snippet from blueprint.yaml
    - name: my-go-template
      type: GoTemplate
      file: "data/template"
  • Template file
    deployitems:
      - name: my-second-deploy-item
        type: landscaper.gardener.cloud/mock
        config:
    {{ include "data/config" . | indent 6 }}
    

State Handling

Depending on the purpose of the execution, Landscaper supports state handling. An execution can provide information that should be kept among multiple evaluations of the execution (e.g. when the installation is updated). The mechanism, how the state is past to and read from an execution depends on its template engine.

Template Engines

The Landscaper currently supports two template engines:

Regardless of the chosen engine, the output is always expected to have the same structure.

⚠️ Note that OS functions are not available for security reasons.

Go Template

The execution type to use for go templates is GoTemplate. As go templates are not valid YAML, they have to be provided as a string. Because this is typically a multi-line string, the | notation is mostly used.

Example

- name: my-go-template
  type: GoTemplate
  template: |
    deployitems:
    - name: my-second-deploy-item
      type: landscaper.gardener.cloud/mock
      config: {{ .imports.config }}
Additional Functions

The GoTemplate executor simply is standard go template enhanced with sprig functions.

The following additional functions are available:

  • include(path string, binding interface{}): string reads and executes a template from the given file with the provided binding (similar to helm's 'include')
  • readFile(path string): []byte reads a file from the blueprints filesystem
  • readDir(path string): []FileInfo returns all files and directories in the given directory of the blueprint's filesystem.
  • toYaml(interface{}): string converts the given object to valid yaml
  • getResource(ComponentDescriptor, keyValuePairs ...string): Resource searches a resource in the given component descriptors that matches the specified selector. The selector are key-value pairs that describe the resource's identity. e.g. getResource .cd "name" "myResource" -> returns the resource with the name myResource
  • getComponent(componentDescriptor, keyValuePairs ...string): ComponentDescriptor searches a component in the given component descriptors that matches the specified selector. The selector are key-value pairs that describe the component reference's identity. e.g. getComponent .cd "name" "myComp" -> seraches in the component descriptor for a component reference with the name myComp and returns the referenced component descriptor.
  • getRepositoryContext(componentDescriptor): RepositoryContext returns the effective repository context of the given component descriptor
  • parseOCIRef(ref string): [2]string parses an oci reference and returns the repository and the version. e.g. host:5000/myrepo/myimage:1.0.0 -> ["host:5000/myrepo/myimage", "1.0.0"]
  • ociRefRepo(ref string): string parses an oci reference and returns the repository. e.g. host:5000/myrepo/myimage:1.0.0 -> "host:5000/myrepo/myimage"
  • ociRefVersion(ref string): string parses an oci reference and returns the version. e.g. host:5000/myrepo/myimage:1.0.0 -> "1.0.0"
  • resolve(access Access): []byte resolves an artifact defined by a typed access definition. The resolve function is currently able to handle artifacts of type ociRegistry, others may be added in the future. The function always returns a byte array of the artifact response
    # e.g for a oci registry artifact
    type: ociRegistry
    imageReference: host:5000/myrepo/myimage:1.0.0
    
State

Old state is provided via an additional state binding. New state is taken from the state node of the rendered template, if it exists.

Example

- name: my-go-template
  type: GoTemplate
  template: |
    state: {{if .state}}{{add .state 1}}{{else}}1{{end}}
    deployitems:
    - name: my-second-deploy-item
      type: landscaper.gardener.cloud/mock
      config: {{ .imports.config }}

Spiff

The execution type to use for spiff templates is Spiff. The template can be provided as either YAML or text.

Example

- name: my-spiff-template
  type: Spiff
  template:
    deployItems:
    - name: my-first-deploy-item
      type: landscaper.gardener.cloud/mock
      config: (( .imports.config ))

or

- name: my-spiff-template
  type: Spiff
  template: |
    deployItems:
    - name: my-first-deploy-item
      type: landscaper.gardener.cloud/mock
      config: (( .imports.config ))
Additional Functions
  • getResource(ComponentDescriptor, keyValuePairs ...string): Resource searches a resource in the given component descriptors that matches the specified selector. The selector are key-value pairs that describe the resource's identity. e.g. getResource .cd "name" "myResource" -> returns the resource with the name myResource
  • getComponent(componentDescriptor, keyValuePairs ...string): ComponentDescriptor searches a component in the given component descriptors that matches the specified selector. The selector are key-value pairs that describe the component reference's identity. e.g. getComponent .cd "name" "myComp" -> seraches in the component descriptor for a component reference with the name myComp and returns the referenced component descriptor.
  • parseOCIRef(ref string): [2]string parses an oci reference and returns the repository and the version. e.g. host:5000/myrepo/myimage:1.0.0 -> ["host:5000/myrepo/myimage", "1.0.0"]
  • ociRefRepo(ref string): string parses an oci reference and returns the repository. e.g. host:5000/myrepo/myimage:1.0.0 -> "host:5000/myrepo/myimage"
  • ociRefVersion(ref string): string parses an oci reference and returns the version. e.g. host:5000/myrepo/myimage:1.0.0 -> "1.0.0"
State

Spiff already has state handling implemented, see here for details.