0

Having dictionary (defined in map.jinja)

{% set intellij = salt['grains.filter_by']({
    'default': {
        'orig_name': 'idea-IC-145.1617.8',
        'download_url': 'www.example.com',         
        'archive_format': 'tar',
        'archive_opts': 'xfz',
        'owner': 'root',
        'owner_link_location': '/blabla/bin/idea',
    },
}, merge=salt['pillar.get']('intellij')) %}

and some function definition accepting arguments almost the same as the dictionary's keys (let's assume the "function" is actually a macro)

{% macro some_macro(state_id, orig_name, download_url, archive_format, owner, archive_opts=None) %}

I would like to filter out some keys so that I can call it like this:

{{ some_macro('some_state', **intellij) }}

I've tried various constructs, like:

{{ some_macro('intellij', **(intellij|rejectattr("owner_link_location"))) }}

which yields

Jinja error: call() argument after ** must be a mapping, not generator

Dict-comprehension (instead of jinja filter) also doesn't work.

How to achieve the aforementioned functionality (filtering out the key or at least calling the function with "extracted" and filtered dictionary in concise way)?

lakier
  • 550
  • 4
  • 16
  • it seems that the definition of 'some_macro' is not consistent with how you call it. can you paste the content of your pillar file to give more detail ? – sel-fish Jul 09 '16 at 23:49
  • Pillar is empty and doesn't override anything. I've fixed typo in question, thank you! – lakier Jul 10 '16 at 21:36
  • It seems that rejectattr can only be used to filter list, but 'intellij' is mapping. If you just want to filter the keys, why not just define the macro as ```some_macro(state_id, orig_name, download_url, archive_format, owner, archive_opts=None, owner_link_location=None)``` – sel-fish Jul 11 '16 at 03:49
  • This macro is used in multiple places and serves sole purpose - I don't wan't do add unrelated argument (thus introducing ambiguity) – lakier Jul 11 '16 at 08:25

1 Answers1

0

The problem you encountered is described here.
There is a trick to work around which looks fine to me.

{% macro some_macro(state_id, orig_name, download_url, archive_format, owner, archive_opts=None) -%}
{% if kwargs | length >= 0 -%}
// implement your macro definition here
{% endif -%}
{% endmacro -%}

The point is that you have to call kwargs if you didn't consume all the variables in mapping.

Then call your macro as :

{{ some_macro('some_state', **intellij) }}
Community
  • 1
  • 1
sel-fish
  • 4,308
  • 2
  • 20
  • 39