Project: KUDO (App Definition and Development / Application Definition & Image Build)
File: 0025-template-to-yaml-function.md

kep-number: 25 title: Template toYaml function short-desc: New toYaml function for use in templates authors: "@porridge" owners: "@porridge" editor: @porridge creation-date: 2020-02-25 last-updated: 2020-03-02 status: implemented see-also: KEP-24 * * * * This KEP describes addition of a function called `toYaml` for use in the operator templates. This enhancement will make it possible for operator developers to allow users to pass arbitrary structured parameters and directly embed them into resources. Make it possible for an operator developer to use a `toYaml` function in their templates on a `.Params` value. Make it possible for an operator user to provide a parameter with value type other than `string`. We rely on to provide this functionality. Make it possible for a user to provide a complex structured parameter value in typical multi-line YAML syntax in a convenient way. This will be addressed by a separate KEP. For now, a user will need to rely on passing the value via a `--parameter` command line flag using JSON syntax (which is a subset of YAML). The idea is to provide an analog of the `toYaml` . Sadly, I could not find any documentation for it, but it is . There were at least a couple of feature requests that would be solved by this enhancement. They were mostly concerned with configuring some aspects of k8s pods: : `nodeSelector`, `podAnnotations`, `resources` and `podAffinity` `nodeAffinity` and `tolerations` The common theme is that these k8s features requires deeply nested YAML syntax ( are 5 levels deep!) Here is how using this might look like: ```yaml apiVersion: apps/v1 kind: Deployment spec: template: metadata: {{- if or .Params.podAnnotations .Params.enableMetrics }} annotations: {{- if .Params.enableMetrics }} prometheus.io/scrape: "true" {{- end }} {{- if .Params.podAnnotations }} {{ toYaml .Params.podAnnotations | trim | indent 8 }} {{- end }} {{- end }} ``` This matches the idiomatic way to do this in Helm. Here is some on the need for `trim` and `indent`. As mentioned in the section, a user would initially pass the value for above example `podAnnotations` parameter like this: ```bash kubectl kudo install theoperator --parameter='{"anntation.io": "somevalue"}' ``` This proposal relies on to provide support for parameter values other than `string`, as this function would be nearly useless without it. However the author of KEP-24 . Being able to just dump a deeply nested data structure in the middle of a template adds a lot of flexibility, but could also open up opportunities for abuse. In the extreme case, one can imagine a template consisting only of a single line: ```yaml {{ .Params.resource }} ``` This would allow the user to pass via the `--parameter` flag a complete resource definition of arbitrary name and type. Since changes of this resource between `kubectl kudo` invocations would be unbounded, it would most likely have unintended consequences (including KUDO controller losing track of created resources). Ultimately, operator developers need to apply this feature with some care. 2020-02-25 - Initial draft. (@porridge) 2020-02-28 - Changed to implementable. (@porridge) 2020-03-02 - Implemented in . (@porridge) In the absence of a `toYaml` function, in order to provide a way to e.g. customize a `podAffinity` setting, the operator developer would need to hand-craft a complex template that would walk the deep data structure provided by a user and re-create it again in YAML. In case of such deeply-nested structures, this template would be very hard to read and error-prone to edit.