Define preference and document on how to deal with nested value defaults
The following discussion from !4521 (merged) should be addressed:
-
@GitLabDuo started a discussion: (+2 comments) The template accesses nested fields without checking if intermediate objects exist. If a user provides partial configuration like
databaseTrafficCapture: {config: {}}
, this will cause template rendering to fail. Consider adding safety checks for each level of nesting.{{- if and .config .config.storage .config.storage.connector .config.storage.connector.provider (ne .config.storage.connector.provider "") -}}
Summary
For nested values, Helm recommends:
For optimal safety, a nested value must be checked at every level
This is necessary because when Helm tries to evaluate foo.bar.baz
, we can't only check whether baz
is present because it might fail to render the template if bar
is null.
Although there are multiple ways of solving this problem:
- Concatenating a conditional when evaluating each level and setting a default.
-
Example using multiple
hasKey
calls. - Pros:
- It's kind of what Helm suggest on its docs.
- Cons:
- If the objects is very long, it can get hard to read multiple conditional checks.
- May not be the most performant due to multiple conditionals.
-
Example using multiple
- Add defaults to all level within our
values.yaml
.- Example.
- Pros:
- It's likely the most performant as it does not required content checking and function calling.
- Cons:
- Pollutes our .Values file which is already very big.
- Converting the root key to a dictionary, then using the
dig
template function to safe navigate and define a default.- Example
- Pros:
- It's clean to read.
- Cons:
- May be the least performant due to converting an object to
dict
and evalutaingdig
multiple times if the nested object is long.
- May be the least performant due to converting an object to
Edited by João Alexandre Cunha