github.com/koderover/helm@v2.17.0+incompatible/docs/chart_template_guide/functions_and_pipelines.md (about)

     1  # Template Functions and Pipelines
     2  
     3  So far, we've seen how to place information into a template. But that information is placed into the template unmodified. Sometimes we want to transform the supplied data in a way that makes it more usable to us.
     4  
     5  Let's start with a best practice: When injecting strings from the `.Values` object into the template, we ought to quote these strings. We can do that by calling the `quote` function in the template directive:
     6  
     7  ```yaml
     8  apiVersion: v1
     9  kind: ConfigMap
    10  metadata:
    11    name: {{ .Release.Name }}-configmap
    12  data:
    13    myvalue: "Hello World"
    14    drink: {{ quote .Values.favorite.drink }}
    15    food: {{ quote .Values.favorite.food }}
    16  ```
    17  
    18  Template functions follow the syntax `functionName arg1 arg2...`. In the snippet above, `quote .Values.favorite.drink` calls the `quote` function and passes it a single argument.
    19  
    20  Helm has over 60 available functions. Some of them are defined by the [Go template language](https://godoc.org/text/template) itself. Most of the others are part of the [Sprig template library](https://godoc.org/github.com/Masterminds/sprig). We'll see many of them as we progress through the examples.
    21  
    22  > While we talk about the "Helm template language" as if it is Helm-specific, it is actually a combination of the Go template language, some extra functions, and a variety of wrappers to expose certain objects to the templates. Many resources on Go templates may be helpful as you learn about templating.
    23  
    24  ## Pipelines
    25  
    26  One of the powerful features of the template language is its concept of _pipelines_. Drawing on a concept from UNIX, pipelines are a tool for chaining together a series of template commands to compactly express a series of transformations. In other words, pipelines are an efficient way of getting several things done in sequence. Let's rewrite the above example using a pipeline.
    27  
    28  ```yaml
    29  apiVersion: v1
    30  kind: ConfigMap
    31  metadata:
    32    name: {{ .Release.Name }}-configmap
    33  data:
    34    myvalue: "Hello World"
    35    drink: {{ .Values.favorite.drink | quote }}
    36    food: {{ .Values.favorite.food | quote }}
    37  ```
    38  
    39  In this example, instead of calling `quote ARGUMENT`, we inverted the order. We "sent" the argument to the function using a pipeline (`|`): `.Values.favorite.drink | quote`. Using pipelines, we can chain several functions together:
    40  
    41  ```yaml
    42  apiVersion: v1
    43  kind: ConfigMap
    44  metadata:
    45    name: {{ .Release.Name }}-configmap
    46  data:
    47    myvalue: "Hello World"
    48    drink: {{ .Values.favorite.drink | quote }}
    49    food: {{ .Values.favorite.food | upper | quote }}
    50  ```
    51  
    52  > Inverting the order is a common practice in templates. You will see `.val | quote` more often than `quote .val`. Either practice is fine.
    53  
    54  When evaluated, that template will produce this:
    55  
    56  ```yaml
    57  # Source: mychart/templates/configmap.yaml
    58  apiVersion: v1
    59  kind: ConfigMap
    60  metadata:
    61    name: trendsetting-p-configmap
    62  data:
    63    myvalue: "Hello World"
    64    drink: "coffee"
    65    food: "PIZZA"
    66  ```
    67  
    68  Note that our original `pizza` has now been transformed to `"PIZZA"`.
    69  
    70  When pipelining arguments like this, the result of the first evaluation (`.Values.favorite.drink`) is sent as the _last argument to the function_. We can modify the drink example above to illustrate with a function that takes two arguments: `repeat COUNT STRING`:
    71  
    72  ```yaml
    73  apiVersion: v1
    74  kind: ConfigMap
    75  metadata:
    76    name: {{ .Release.Name }}-configmap
    77  data:
    78    myvalue: "Hello World"
    79    drink: {{ .Values.favorite.drink | repeat 5 | quote }}
    80    food: {{ .Values.favorite.food | upper | quote }}
    81  ```
    82  
    83  The `repeat` function will echo the given string the given number of times, so we will get this for output:
    84  
    85  ```yaml
    86  # Source: mychart/templates/configmap.yaml
    87  apiVersion: v1
    88  kind: ConfigMap
    89  metadata:
    90    name: melting-porcup-configmap
    91  data:
    92    myvalue: "Hello World"
    93    drink: "coffeecoffeecoffeecoffeecoffee"
    94    food: "PIZZA"
    95  ```
    96  
    97  ## Using the `default` function
    98  
    99  One function frequently used in templates is the `default` function: `default DEFAULT_VALUE GIVEN_VALUE`. This function allows you to specify a default value inside of the template, in case the value is omitted. Let's use it to modify the drink example above:
   100  
   101  ```yaml
   102  drink: {{ .Values.favorite.drink | default "tea" | quote }}
   103  ```
   104  
   105  If we run this as normal, we'll get our `coffee`:
   106  
   107  ```yaml
   108  # Source: mychart/templates/configmap.yaml
   109  apiVersion: v1
   110  kind: ConfigMap
   111  metadata:
   112    name: virtuous-mink-configmap
   113  data:
   114    myvalue: "Hello World"
   115    drink: "coffee"
   116    food: "PIZZA"
   117  ```
   118  
   119  Now, we will remove the favorite drink setting from `values.yaml`:
   120  
   121  ```yaml
   122  favorite:
   123    #drink: coffee
   124    food: pizza
   125  ```
   126  
   127  Now re-running `helm install --dry-run --debug ./mychart` will produce this YAML:
   128  
   129  ```yaml
   130  # Source: mychart/templates/configmap.yaml
   131  apiVersion: v1
   132  kind: ConfigMap
   133  metadata:
   134    name: fair-worm-configmap
   135  data:
   136    myvalue: "Hello World"
   137    drink: "tea"
   138    food: "PIZZA"
   139  ```
   140  
   141  In an actual chart, all static default values should live in the values.yaml, and should not be repeated using the `default` command (otherwise they would be redundant). However, the `default` command is perfect for computed values, which can not be declared inside values.yaml. For example:
   142  
   143  ```yaml
   144  drink: {{ .Values.favorite.drink | default (printf "%s-tea" (include "fullname" .)) }}
   145  ```
   146  
   147  In some places, an `if` conditional guard may be better suited than `default`. We'll see those in the next section.
   148  
   149  Template functions and pipelines are a powerful way to transform information and then insert it into your YAML. But sometimes it's necessary to add some template logic that is a little more sophisticated than just inserting a string. In the next section we will look at the control structures provided by the template language.
   150  
   151  ## Operators are functions
   152  
   153  Operators are implemented as functions that return a boolean value. To use `eq`, `ne`, `lt`, `gt`, `and`, `or`, `not` etcetera place the operator at the front of the statement followed by its parameters just as you would a function. To chain multiple operations together, separate individual functions by surrounding them with parentheses.
   154  
   155  ```yaml
   156  {{/* include the body of this if statement when the variable .Values.fooString exists and is set to "foo" */}}
   157  {{ if and .Values.fooString (eq .Values.fooString "foo") }}
   158      {{ ... }}
   159  {{ end }}
   160  
   161  
   162  {{/* include the body of this if statement when the variable .Values.anUnsetVariable is set or .values.aSetVariable is not set */}}
   163  {{ if or .Values.anUnsetVariable (not .Values.aSetVariable) }}
   164     {{ ... }}
   165  {{ end }}
   166  ```
   167  
   168  Now we can turn from functions and pipelines to flow control with conditions, loops, and scope modifiers.