Nested grains use

1,417 views
Skip to first unread message

Karl Latiss

unread,
May 3, 2013, 3:25:49 AM5/3/13
to salt-...@googlegroups.com
I'm trying to understand how to use nested grains values. I'm using 0.14

On my minion I have the following defined:

# configure server roles
grains:
  roles:
    - infrastructure
    - databaseserver:
      - memoryprofile: 1GB

On my master I see:

$ salt 'hostname' grains.item roles
hostname:
  roles:
      infrastructure
      {'databaseserver': [{'memoryprofile': '1GB'}]}

If I ping based just on the infrastructure role then all is OK:

$ salt -G 'roles:infrastructure' test.ping
hostname:
    True

But I would like to address the host by it's memoryprofile value in this case. How do I do that? I've tried all sorts of variations from

$ salt -G 'roles:databaseserver' test.ping
No minions matched the target. No command was sent, no jid was assigned.

to

$ salt -G 'roles:databaseserver:memoryprofile:1GB' test.ping
No minions matched the target. No command was sent, no jid was assigned.

to the bizarre

$ salt -G 'roles:{'databaseserver': [{'memoryprofile': '1GB'}]}' test.ping
No minions matched the target. No command was sent, no jid was assigned.

There's a right way to do this I'm sure but I can't see to find it. Or the appropriate documentation.

If anyone has some insight it would be appreciated.

Karl.

Karl Latiss

unread,
May 6, 2013, 6:02:19 AM5/6/13
to salt-...@googlegroups.com
No suggestions? Maybe everyone is doing this with pillars?

Thomas S Hatch

unread,
May 6, 2013, 2:30:05 PM5/6/13
to salt-...@googlegroups.com
So this is because databaseserver is in a list, the matching just looks for a string in a list and does not dive down deeper, try grains like this:

grains:
  roles:
    - infrastructure
  database:
    memoryprofile: 1GB

Then match on the database:memoryprofile grain

Thomas S. Hatch  |  Founder, CTO


5272 South College Drive, Suite 301 | Murray, UT 84123


--
You received this message because you are subscribed to the Google Groups "Salt-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to salt-users+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Karl Latiss

unread,
May 7, 2013, 7:19:03 AM5/7/13
to salt-...@googlegroups.com
OK, that works. To extend this to what I wanted to do originally I now have:

grains:
  roles:
    - infrastructure
    - databaseserver
  databaseserver:
    memoryprofile: 1GB
    maxpacketsize: 10M

Thanks for the push in the right direction!

Karl.

Karl Latiss

unread,
May 7, 2013, 8:19:14 AM5/7/13
to salt-...@googlegroups.com
Hmm, spoke too soon. I'm close as

$ salt -G 'databaseserver:memoryprofile:1GB' test.ping
hostname:
    True

works, and

$ salt 'hostname' grains.item databaseserver
hostname:
  databaseserver: {'memoryprofile': '1GB'}

shows me what I expect. However when I try to test:

{% if 'memoryprofile:1GB' in grains['databaseserver'] %}

I get the below output which, unfortunately, I cannot decipher:

hostname:
    Data failed to compile:
----------
    Rendering SLS mysql failed, render error:
Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/salt/state.py", line 1779, in render_state
    fn_, self.state.rend, self.state.opts['renderer'], env, sls, rendered_sls=mods)
  File "/usr/lib/python2.6/site-packages/salt/template.py", line 61, in compile_template
    ret = render(input_data, env, sls, **render_kwargs)
  File "/usr/lib/python2.6/site-packages/salt/renderers/jinja.py", line 36, in render
    'Unknown render error in jinja renderer'))
SaltRenderError: Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/salt/utils/templates.py", line 55, in render_tmpl
    output = render_str(tmplstr, context, tmplpath)
  File "/usr/lib/python2.6/site-packages/salt/utils/templates.py", line 98, in render_jinja_tmpl
    output = jinja_env.from_string(tmplstr).render(**context)
  File "/usr/lib64/python2.6/site-packages/jinja2/environment.py", line 669, in render
    return self.environment.handle_exception(exc_info, True)
  File "<template>", line 30, in top-level template code
TypeError: argument of type 'StrictUndefined' is not iterable


Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/salt/utils/templates.py", line 55, in render_tmpl
    output = render_str(tmplstr, context, tmplpath)
  File "/usr/lib/python2.6/site-packages/salt/utils/templates.py", line 98, in render_jinja_tmpl
    output = jinja_env.from_string(tmplstr).render(**context)
  File "/usr/lib64/python2.6/site-packages/jinja2/environment.py", line 669, in render
    return self.environment.handle_exception(exc_info, True)
  File "<template>", line 30, in top-level template code
TypeError: argument of type 'StrictUndefined' is not iterable

Kevin B

unread,
May 8, 2013, 11:46:43 AM5/8/13
to salt-...@googlegroups.com
I've found the only way to match nested grains like that in states is:

{% if grains.databaseserver.memoryprofile == '1GB' %}

Karl Latiss

unread,
May 9, 2013, 7:30:01 AM5/9/13
to salt-...@googlegroups.com
That's it! Thank-you.

Makes me wonder if I'm doing it right though...

Thomas S Hatch

unread,
May 9, 2013, 7:56:07 PM5/9/13
to salt-...@googlegroups.com
I would do:

{% if salt['grains.get']('databaseserver:memoryprofile') == '1GB' %}

since the get function is safe, it won't stack trace if something is not present, it just returns None

Thomas S. Hatch  |  Founder, CTO


5272 South College Drive, Suite 301 | Murray, UT 84123


Kevin B

unread,
May 9, 2013, 10:00:46 PM5/9/13
to salt-...@googlegroups.com
Awesome, for some reason I couldn't get this to work previously with grains.get. Probably a syntax issue as it works now.
Reply all
Reply to author
Forward
0 new messages