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:
deployExecutions
for rendering deployitemsexportExecutions
for rendering exportssubinstallationExecutions
for rendering nested installations
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.
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 areGoTemplate
andSpiff
. -
file
string [optional] If this property is set, the template is read from the specified file of the blueprint file structure. Exactly one offile
andtemplate
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 offile
andtemplate
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: ...
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 }}
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.
The Landscaper currently supports two template engines:
GoTemplate
Go Template enhanced with sprig functions.Spiff
Spiff++ templating.
Regardless of the chosen engine, the output is always expected to have the same structure.
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 }}
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 filesystemreadDir(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 yamlgetResource(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 namemyResource
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 namemyComp
and returns the referenced component descriptor.getRepositoryContext(componentDescriptor): RepositoryContext
returns the effective repository context of the given component descriptorparseOCIRef(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 typeociRegistry
, 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
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 }}
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 ))
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 namemyResource
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 namemyComp
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"
Spiff already has state handling implemented, see here for details.