Saltstack Using Jinja variables inside Jinja - jinja2

I am writing a salt state that will check the value of a registry key. This is returning 'NULL'. I suspect that my 'getregvalue' variable is not resolving with the variables i have passed to cmd.run. This works as expected when the -Path and -Name values are hardcoded. How do i pass the -Path and -Name variables dynamically correctly?
{% for regconfig in registryconfig.settings %}
{% set getregvalue = salt['cmd.run']('Get-ItemPropertyValue -Path regconfig.hive ~ ":\" ~ regconfig.path -Name regconfig.vname',shell='powershell') %}
{% endfor %}
c:\temp\debug.txt:
file.managed:
- contents: |
{{ getregvalue |yaml(False) |indent(8) }}
This is the config file
{%- load_yaml as registrysettings %}
dev:
settings:
- hive: 'HKLM'
path: 'SOFTWARE\Database Settings\dbstate'
vname: ConnectionString
{%- endload %}
{%- set registryconfig = salt['grains.filter_by'](registrysettings,
grain='env') %}

You make sure strings are quoted, and code is not:
("Get-ItemPropertyValue -Path " ~ regconfig.hive ~ ":\\" ~ regconfig.path ~ " -Name " ~ regconfig.vname, shell="powershell")
If the path and name also need quoting for PowerShell, then include those too:
("Get-ItemPropertyValue -Path '" ~ regconfig.hive ~ ":\\" ~ regconfig.path ~ "' -Name '" ~ regconfig.vname ~ "'", shell="powershell")

{% set getregvalue = salt['cmd.run']("Get-ItemPropertyValue -Path '" ~ regconfig.hive ~ ":\\" ~ regconfig.path ~ '" -Name '" ~ regconfig.vname ~ "'", shell='powershell') %}
Thanks to #Orangedog for pointing me in the right direction. Quoting the strings AND the arguments solved this for me.

Related

Using Saltstack cmd.script with args to Insert Jinja Variable

I am running a powershell script to obtain a particular user's credentials, and then use those credentials in a salt state. This works fine when the username is hardcoded directly in the powershell script. But, I am unable to pass the username as an argument. Here is my salt state:
{% set creds = salt['cmd.powershell']('C:\test2.ps1' 'username') %}
test_output:
cmd.run:
- name: echo {{ creds }}
I have also tried this too...but it doesn't work.
{% set creds = salt['cmd.script'](shell='powershell' source='C:\test2.ps1' args='username')
%}
How do i correctly pass an argument to my powershell script to set my variable?
The rules for strings and function calls are the same in Jinja as for Python. Either " or ' are the string delimiters, and \ is the escape character. Function arguments are separated by commas.
{% set creds = salt['cmd.powershell']('C:\\test2.ps1 username') %}
For cmd.script, the source should be a remote URL, not a local file.
{% set creds = salt['cmd.script'](shell='powershell', source='salt://path/test2.ps1', args='username') %}

Concatenating a variable in Jinja with a single quote

I'm having trouble trying to concatenate variables (one with a single quote) in Jinja. My code looks like this:
{%- set my_quote = "'" -%}
{%- set invocation = invocation_id -%}
And the output I'm attempting is this:
{{ invocation ~ my_quote }}
The output from this is:
f21f9039-44e5-452f-8d7a-ee64245ada23'
Ok great! Now when I attempt to add the single quote to the beginning as well:
{{ my_quote ~ invocation ~ my_quote }}
The output is the invocation variable value without any single quotes:
f21f9039-44e5-452f-8d7a-ee64245ada23
How can I get this to output both single quotes properly?
Try the following:
"'{{ invocation_id }}'"
oh I love this question and the great reproducible example you provided. First thought, what happens if you escape the ' like this?
{%- set my_quote = "\'" -%}
Is there a reason it has to be part of the variable?
Could you do:
'{{ invocation }}'

Replace and eval in Jinja

I have a string like this as Jinja variable:
foo-VERSION-bar
I want to replace VERSION with {{ grains.lsb_distrib_release }} and I want this to get evaluated.
if grains.lsb_distrib_release contains 123 I want the result to be foo-123-bar.
How to replace and eval in jinja?
Set value of your grain to a variable:
{% set version = salt['grains.get']('lsb_distrib_release', {}) %}
Use Jinja replace function:
{{ "foo-VERSION-bar"|replace("VERSION", version) }}
Without using replace Jinja filter, you can use its concatenation possibilities
{{ 'foo-' ~ salt['grains.get']('lsb_distrib_release') ~ '-bar' }}

Liquid map error "After parsing a value an unexpected character was encountered"

I have a very simple Liquid map (extract here below):
{
{% if content.DisplayLastName__c %}
"DisplayLastName__c": "{{ content.DisplayLastName__c }}",
{% endif %}
}
The input message of the map is the following:
{
"DisplayLastName__c": "é\" r",
"FirstName": "é\""
}
I got this error due to the fact that there is a \" in one field: "After parsing a value an unexpected character was encountered".
Am I missing something?
The following worked for me, however I don't fully know why:
{% assign vDescription = system.Data.Description | Replace: '\"', '\"' %}

Conditional text in jinja2 templates for ansible

I have playbook which may set lot of options for the daemon command line. I want to allow set them all from variables, but the same time I want to make them all optional.
Now I have template (j2) with all variables mandatory:
{% for router in flowtools.captures %}
-d {{router.debug_level}} -e {{router.expire_count}} -E {{router.expire_size}} -f {{router.fiter_name}} -F {{router.filter_definition}} -n {{router.rotations}} -N {{router.netsting_level}} -S {{router.start_interval}} -t {{router.tag_name}} -T {{router.active_def}} -V {{pdu_version}} -w {{router.workdir}} -x {{router.xlate_fname}} -z {{router.z_level}}
{% endfor %}
I want:
To allow undefined variables in 'router' (without failing a playbook).
Not to include option (-z, -b, etc) to the output if related variable is empty.
For example above, if flowtools.captures[0] contains only debug_level=2 and workdir=/tmp it should generate:
-d 2 -w /tmp.
I can add huge list of {% if %}'s but this would be very bulky. Is it possible to make it gracefully?
Well, after some struggle I made
vars.yml:
flowtools_capute_options:
byte_order: ' -b '
workdir: ' -w '
...etc...
template.j2:
{% for router in flowtools.captures %}
{% for opt in router %}
{{flowtools_capute_options[opt]}} {{-router[opt]-}}
{% endfor %}
{% endfor %}