2

Having issues iterations via pillar data and jinja template. I took most of the template from a working salt/pillar installation but now failing to work in new environment.

I have tried several different syntaxes with the implementation of the iteration but still get same error.

ServerName:

Data failed to compile:

Rendering SLS 'base:pillar_lab_user' failed: Jinja variable 'str object' 

has no attribute 'iteritems'

Jinja Template

{% set users = salt['pillar.get']('XXXXXXX') %}
{% for user, args in users.iteritems() %}
{{ user }}:
  user.present:
    - fullname: {{ args.fullname }}
    - uid: {{ args.uid }}
    - gid_from_name: True
    - shell: {{ args.shell }}
{% if not args.empty_password == true %}
    - password: {{ args.password }}
{% else %}
    - empty_password: {{ args.empty_password }}
{% endif %}
{% if 'groups' in args %}
    - groups: {{ args['groups'] }}
{% endif %}


{% endfor %}

Pillar Data

users:
  user1:
    fullname: User1 Fullname
    uid: 951
    gid: 951
    shell: /bin/bash
    groups:
      - sudo
      - admin
    password: (REMOVED)
    pub_ssh_keys: (REMOVED)

  user2:
    fullname: User2 Fullname
    uid: 955
    gid: 955
    shell: /bin/bash
    groups:
     - sudo
     - admin
    password: (REMOVED)
    pub_ssh_keys: (REMOVED)

{% for user, args in users.iteritems() %}

What is the correct syntax for iteritems and accessing this data via a jinja template. I have tried many variations of this syntax but still getting the

ServerName:
    Data failed to compile:
----------
     Rendering SLS 'base:pillar_lab_user' failed: Jinja variable 'str object' 

has no attribute 'iteritems'

EDIT

This was all user error, the pillar configuration was malformed. I removed the first line

"{% set users = salt['pillar.get']('XXXXXXX') %}" 

so I didn't use pillar.get and targeted with pillar top.sls. It works properly now.

Michał Zaborowski
  • 3,911
  • 2
  • 19
  • 39

1 Answers1

0

Your data should fail with :
Rendering SLS 'base:so' failed: Jinja variable 'dict object' has no attribute 'empty_password'

The reason why you see this error must be caused by non-existing pillar data.

You've pasted full pillar data but left XXXXXXX in state file. It suggest that fix could possibly be as simple as:

{% set users = salt['pillar.get']('users') %}

or if it is not the case: check if you use pillarenv, then remember to pass the correct one, you can simply verify this in command line:

salt 'your minion' pillar.get users

If it doesn't return your dictionary then try:

salt 'your minion' pillar.get users pillarenv=your_pillar_env
lakier
  • 550
  • 4
  • 16
  • XXXXXX is just to hide the real names of files. Yeah, there is no empty_password field. I don't think this is the problem. – UMBC Developer Jan 31 '18 at 20:13
  • 2
    I think so, however in your example you should have placed `salt['pillar.get']('users')`. Paste your salt-master config, what does the shell command: `salt 'your minion' pillar.get users` return? Do you use `pillarenv`? – lakier Feb 01 '18 at 10:05
  • I'm pretty sure @lakier is either right or headed in the right direction w.r.t. debugging your situation. It definitely sounds like `users` doesn't have a value when you call `iteritems()`. I'm not 100% sure, but your exception sounds like `users` is set to a string (i.e., Jinja variable 'str object') which makes sense because I think you get an empty string back when the pillar data you request doesn't exist. – Mike Feb 02 '18 at 10:35
  • This is all user error, the pillar configuration was malformed. i removed the first line "{% set users = salt['pillar.get']('XXXXXXX') %}" so I didn't use pillar.get and targeted with pillar top.sls. It works properly now. – UMBC Developer Feb 08 '18 at 09:56