salt: {{salt.pillar.get()}} / {{salt.grains.get()}} shorthand is broken

Description of Issue/Question

It’s not possible to use salt.pillar.get('something') in state file.

Setup

Add a call to salt.pillar.get to sls.

Steps to Reproduce Issue

Run the state (in here I can only reproducer with salt-ssh so far). The error is

Rendering exception occurred: Jinja error: get() takes exactly 3 arguments (2 given)

(same for pillar and grains)

salt['pillar.get']() works as expected. I was able to workaround the issue with the following renderer prepended to jinja|yaml:

def render(data, saltenv='base', sls='', argline='', **kwargs):
  data_str = data.read()
  data_str = (data_str
    .replace('salt.pillar.get(', 'salt["pillar.get"](')
    .replace('salt.grains.get(', 'salt["grains.get"]('))
  return StringIO(data_str)

Versions Report

Salt Version:
           Salt: 2017.7.0-267-gcc72f1a

Dependency Versions:
           cffi: Not Installed
       cherrypy: Not Installed
       dateutil: Not Installed
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
          ioflo: Not Installed
         Jinja2: 2.9.6
        libgit2: Not Installed
        libnacl: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.4.8
   mysql-python: Not Installed
      pycparser: Not Installed
       pycrypto: 2.6.1
   pycryptodome: Not Installed
         pygit2: Not Installed
         Python: 2.7.10 (default, Feb  7 2017, 00:08:15)
   python-gnupg: Not Installed
         PyYAML: 3.12
          PyZMQ: 16.0.2
           RAET: Not Installed
          smmap: Not Installed
        timelib: Not Installed
        Tornado: 4.5.1
            ZMQ: 4.2.2

System Versions:
           dist:
        machine: x86_64
        release: 16.6.0
         system: Darwin
        version: 10.12.5 x86_64

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Comments: 20 (14 by maintainers)

Commits related to this issue

Most upvoted comments

Your own saltstack team are recommending salt.pillar.get

That’s not a recommendation, just a statement. They’re explaining the difference between pillar.get() and salt.pillar.get().

salt.pillar.get() is a simple function call on some ‘salt’ object

But it’s not though, it’s a function call on some “pillar” object that’s an attribute of some “salt” object. And that “pillar” object is completely different to the injected pillar object.

salt[‘pillar.get’] returns what exactly

A function. You don’t see it in library APIs because you can use imports instead. But you do see it in Python code generally because it didn’t have any switch statements until 3.10.

My IDE isn’t going to help me

No. It’s not going to help with salt.pillar.get either.

they didn’t work as I expected

Not sure what you were expecting. pillar is for all intents and purposes just a regular dict.

which bits of the cache they skip

They don’t. The pillar dict is the cache. It’s salt["pillar.get"] that bypasses it.

I should avoid them

You’ll get better performance if you use pillar. The advantage of salt["pillar.get"] is the key traversal syntax.

I’m able to reproduce this with the following test case:

[root@877f94bae2da /]# cat /srv/pillar/test.sls 
test: test1
[root@877f94bae2da /]# cat /srv/pillar/top.sls 
base:
  '*':
    - test
[root@877f94bae2da /]# cat /srv/salt/test.sls 
{% set test = salt.pillar.get('test') %}

echo {{ test }}:
  cmd.run
[root@877f94bae2da /]# 

This is only broken on salt-ssh and it is not a regression. I can see the same failed behavior all the way back in 2016.3 branch. We will need to get this fixed