Salt: Error raised by pillar "is defined" when pillar key parent also isn't defined

Created on 25 Jan 2017  路  7Comments  路  Source: saltstack/salt

Description of Issue/Question

When using the "is defined" feature within templated files. The "is defined" check will throw an exception if the key's parent is equally undefined.

Setup & Steps to Reproduce Issue

Pillar definition

Level1:
  Level2.1:
    Level3.1:
      Level 4
  Level2.2:
    Level3:
      Level 4

If you use
{% if pillar['Level1']['Level2.1']['Level3.1'] is defined %}
This will work fine..
Although if you change it to this

Level1:
  Level2.2:
    Level3:
      Level 4

Although if you remove the Level 2.1 path, the check throws an exception when checking for Level3.1 because Level 2.1 is not defined.
This should just return a "not defined" result.

Error:
ID: /etc/salt/master
Function: file.blockreplace
Result: False
Comment: An exception occurred in this state: Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/salt/state.py", line 1744, in call
*cdata['kwargs'])
File "/usr/lib/python2.7/site-packages/salt/loader.py", line 1702, in wrapper
return f(
args, *kwargs)
File "/usr/lib/python2.7/site-packages/salt/states/file.py", line 3623, in blockreplace
context=context)
File "/usr/lib/python2.7/site-packages/salt/states/file.py", line 743, in _get_template_texts
*
kwargs
File "/usr/lib/python2.7/site-packages/salt/modules/cp.py", line 261, in get_template
*kwargs)
File "/usr/lib/python2.7/site-packages/salt/fileclient.py", line 676, in get_template
*
kwargs
File "/usr/lib/python2.7/site-packages/salt/utils/templates.py", line 178, in render_tmpl
output = render_str(tmplstr, context, tmplpath)
File "/usr/lib/python2.7/site-packages/salt/utils/templates.py", line 386, in render_jinja_tmpl
buf=tmplstr)
SaltRenderError: Jinja variable 'dict object' has no attribute 'Level2.1'
Started: 14:41:52.397823
Duration: 97.836 ms
Changes:
Changed the attribute to match the example and this is me adding values to the master conf file.

Versions Report

Salt Version:
Salt: 2016.11.0

Dependency Versions:
cffi: Not Installed
cherrypy: Not Installed
dateutil: Not Installed
gitdb: Not Installed
gitpython: Not Installed
ioflo: Not Installed
Jinja2: 2.7.2
libgit2: Not Installed
libnacl: Not Installed
M2Crypto: Not Installed
Mako: Not Installed
msgpack-pure: Not Installed
msgpack-python: 0.4.6
mysql-python: Not Installed
pycparser: Not Installed
pycrypto: 2.6.1
pygit2: Not Installed
Python: 2.7.5 (default, Nov 20 2015, 02:00:19)
python-gnupg: Not Installed
PyYAML: 3.11
PyZMQ: 14.7.0
RAET: Not Installed
smmap: Not Installed
timelib: Not Installed
Tornado: 4.2.1
ZMQ: 4.0.5

System Versions:
dist: centos 7.2.1511 Core
machine: x86_64
release: 3.10.0-327.22.2.el7.x86_64
system: Linux
version: CentOS Linux 7.2.1511 Core

expected-behavior

Most helpful comment

For using is defined, you should use the dot notation that jinja allows.

{% if pillar.Level1.Level2.Level3 is defined %}

If you use the dictionary version, it actually needs to be in the dictionary.

You could also use the pillar.get module to check.

{% if salt.pillar.get('Level1:Level2.1:Level3.1:', None) is not None %}

All 7 comments

For using is defined, you should use the dot notation that jinja allows.

{% if pillar.Level1.Level2.Level3 is defined %}

If you use the dictionary version, it actually needs to be in the dictionary.

You could also use the pillar.get module to check.

{% if salt.pillar.get('Level1:Level2.1:Level3.1:', None) is not None %}

@gtmanfred thanks for the reply and sorry for the delay in replying.. i've tried those two examples but they dont' work for me. do you know where i can find the docs to read through this use of "is defined"?
I'm failing to find examples of them or do you have a example of the check that is safe to share?

If i try the pillar.level1 approach it still tells me that the level2 element doesn't exist, therefore doesn't check the level3 element exists or not and failes to apply the state
when i try the salt.pillar.get approach it throws the following error
Unable to manage file: Jinja syntax error: no test named 'None'; line 23
when i make it lower none t then throws the same error about no attribute matching the level2

I've tried
{% if pillar.salt.masters.syndic_master is defined %}
and
{% if salt.pillar.get('salt:masters:syndic_master', none) is not none %}
and
{% if salt.pillar.get('salt:masters:syndic_master', None) is not None %}

none of which actually work. They all complain that salt:masters doesn't exist in this servers pillar data

Also. is it actually expected behavour for it to throw an exception? surely it should handle the exception and just return false if it's not there, even if the parent element isn't there.

Ok, apparently i was mistaken. In order for it to do multiple levels deep, all the levels before the last level have to be defined.

And there does not appear to be an is None check defined for jinja. You can just do

{%- if salt.pillar.get('salt:masters:syndic_master', None) != None %}
{%- if salt.pillar.get('salt:masters:syndic_master') %}

Both of those work.

Rather than closing this can we not make it a feature request? or do i need to raise a seperate issue for that?
I don't think this should be expected behaviour personally.

This would be something that needs to be added to jinja.

I've also stumbled upon this today. It really would be a great feature - what can we do have it implemented? :)

Was this page helpful?
0 / 5 - 0 ratings