Helm using ternary with condition checking if list is empty - kubernetes-helm

I am using ternary operand to set values to a variable in my helm template. I am unable to get the condition to check if a list is defined.
{{- $environment_names:= ternary $service.environments $.Values.default.environment_names $service.environments }}
executing "root-app/templates/applications.yaml" at <$service.environments>: wrong type for value; expected bool; got interface {}
is there a possibility to convert this map to boolean? I tried bool and lengthwhich are not functions in helm.

It seems like you can use the default template function here: if $service.environments is defined, use its value, but if not (if it's zero, nil, empty string, or otherwise "falsey") use the default value.
{{- $environment_names := $service.environments | default $.Values.default.environment_names }}

I figured out how I could make it working
{{- $environment_names:= ternary $service.environments $.Values.default.environment_names (hasKey $service "environments") }}

Related

Helm template check if boolean value is actually empty not false

How to tell if a value, more specifically a a boolean typed value is empty in gotpl alias helm template?
How to tell if a simple value is empty?
You have multiple options, how to tell if a normal (not boolean) value is empty.
A very brute force and quite long way is to put an if statement around your node such as
{{ if .Values.simpleText }}
isEmpty: false
{{ end }}
This will evaulate isEmpty as false only if there is any value inside .Values.simpleText
A better way to do this is to use the inbuilt empty function:
isEmpty2: {{ empty .Values.simpleText }}
This does the same as the first example just shorter and arguably more
readable
The issue with theese methods is that if you have a node which is a bool theese methods wont work.
#values.yaml
myBool: false
#-----------------------------------------
#template.yaml
isBoolEmpty: {{ empty .Values.myBool }}
#-----------------------------------------
#output
isBoolEmpty: true
This will claim that .Values.myBool is empty even tho it clearly has
a value which is false.
Now there is an option to check if a value is nil
isNil: {{ eq nil .Values.nilValue }}
This will result as true if the value is indeed nil ( nilValue: ) but as soon as you have a value inside nilValue you will get a type exception.
The solution that I found and seemed the easiest to understand and to use is:
{{ if (quote .Values.myBool | empty) }}
isActuallyEmpty: ".Values.myBool is empty"
{{ else }}
isActuallyEmpty: ".Values.myBool has a false or true value"
{{ end }}
I am sorry if this is very trivial but I know that I was struggleing with this question for some time.

How to check whether hash has a value for the key in puppet

I have a hash defined as below:
Hash[String, String] $hashtest = { "abc" => "test1", "xyz" => "test2" },
I have String variable, I need to search for the given key in the hash and if a value is found, I need to assign that value to the variable "result" otherwise I need to assign a default value "test". How can I do this is in puppet? Or only way to do this is using if else condition?
It should be similar like this, but the below code is not working. Kindly correct me what I'm doing wrong.
String $variable = $hashtest[$key] ? { true => $hashtest[$key], false => "test" },
It would be really helpful if someone helps me with this thanks in advance.
I am assuming in your pseudocode you are intending to assign a value with a return from a selector, and not also providing a pseudocode for a ternary-like expression in Puppet. With that in mind, we can achieve this with something similar to Python:
String $variable = $key in $hashtest ? {
true => $hashtest[$key]
false => "test"
}
Note that prior to Puppet 4 you would need the has_key? function (analogous to has_key Hash method in Ruby) from stdlib:
String $variable = has_key($hashtest, $key) ? {
true => $hashtest[$key]
false => 'test'
}
In stdlib there is also a function roughly equivalent to a "null coalescing" operator in other languages (null being roughly equivalent to undef type in Puppet and nil in Ruby) that would provide a cleaner expression:
String $variable = pick($hashtest[$key], 'test')
Similar to the coalescing patterns in other languages, pick will return the first argument that is not undef or empty.
As well as matts answer you can also use the following
$variable = $hashtest[$key].lest || { 'test' }
$variable = ($key in $hashtest).bool2str($hashtest[$key], 'test')
$variable = $hashtest.has_key($key).bool2str($hashtest[$key], 'test')
All of these options are missing the most simple and powerful option that's been available from the core library since puppet 6; the get function.
The get function allows you specify a dot separated path of nested keys to look up as the first argument, and a default value for the second. By default, it will return undef if a value cannot be found, making it ideal for use in conditional expressions since undef is the only value in puppet that automatically converts to false. You can even pass a lambda to it to handle missing values.
In your case, the answer is as simple as $variable = $hashtest.get($key, 'test') or $variable = get($hashtest, $key, 'test'), though I personally find the first option easier to read.

unable to pass dict into tpl function (actually anything but <dot>')

I'm new to helm/go templating, and it seems that I still don't understand how context work. Can someone explain, where is problem and why dict cannot be used like this?
I have this template in file stubs/.test.yaml (which I'd like to use with tpl function):
test: abc
test2: {{.Values.key}}
in values.yaml there is just:
key: value
and I include this template like this:
{{ tpl (.Files.Get "stubs/.test.yaml" ) (.) }}
produces:
test: abc
test2: value
So I loaded file from stubs/.test.yaml, and passed it current (root) context, and .Values.key was found and substituted. As expected.
Now lets redefine stubs/.test.yaml as:
test: abc
test2: {{.key}}
and pass a dict as a context when substituting template, as:
{{ tpl (.Files.Get "stubs/.test.yaml" ) (dict "key" .Values.key) }}
so I'd expect the same result, since I passed dict in place of root context, dict has single value named key, with value taken from .Values.key, which is correctly referenced in that template. But I got:
error calling tpl: cannot retrieve Template.Basepath from values inside tpl function: test: abc
test2: {{.key}}: "BasePath" is not a value
instead. What is happening here?
EDIT: I was testing it more, and it's not about dict. I have to pass . as second parameter into tpl function, otherwise it fails.
Version 3.10
I think I found answer in this issue
IIUC: before tpl starts, it creates object .Template (see builtin_objects) in root context, where there are data about currently processed template. So if you are using tpl you must not change context and pass ., or you must pass something as context, from what is valid $.Template accessible.
So if we're passing dict as in example in my question:
{{ tpl (.Files.Get "stubs/.test.yaml" ) (dict "key" .Values.key) }}
it will not work. But if you extend dict definition like this:
{{ tpl (.Files.Get "stubs/.test.yaml" ) (dict "key" .Values.key "Template" $.Template) }}
it will work now.

Drupal 8 - how to get exposed filters value in preprocess_views_view

I'm using preprocess_views_view to define some new variables and pass them to a twig template.
In order to define these variables I need to access the exposed filters input values, but I can't seem to figure out how:
function my_modules_preprocess_views_view(&$variables) {
$view = $variables['view'];
// Here I would need to access the exposed filters value
$exposed_filter_value = "the_value";
$variables["foo"] = "Something based on the exposed filters value";
}
I would be very grateful for any clues - cheers!
In a hook_preprocess_views_view() implementation in your theme or module:
$values = $view->getExposedInput();
// for example $values["color"];
Or, you can access the values directly from the views-view.html.twig template:
// Assuming `color` is configured to be the Filter identifier in the
// view's Filter Criteria exposed filter.
{{ view.getExposedInput.color }}
I had problems with #Hubert's solution and managed to get it to work with:
$variables["searchInputValue"] = $view->exposed_raw_input['query'];

mongodb - mapReduce() scope - Undefined values are converted into null values

If I put a variable with an undefined value into the "scope" parameter of mapReduce(), then the map function will receive the variable with a null value (instead of the undefined value). Is that correct?
For example (javascript skeleton for the "mongo" command):
db.mycol.mapReduce(
f_map,
f_reduce,
{
scope: { myvar: undefined}
}
);
function f_map()
{
print("myvar: " + myvar);
}
That will print "myvar: null" (instead of "myvar: undefined") into the server log (into the replicaset member log). Are undefined values converted automatically to null values when passing through mapReduce()?
Yes undefined values get translated into null values in mongodb's v8 engine.
The reason for this is to keep backwards compatibility with the older Spider Monkey JS engine and not break existing code that relied on that behaviour.