Search code examples
salt-stack

How to merge base values into grains.filter_by?


I have a problem when using the SaltStack formula "packages". I try to follow the guidelines and simply it for my needs. I need to :

  • install some base packages that does not need a filter
  • install some osfinger dependents packages But when I ask to know which packages were installed, I only get the osfinger ones.

Here my code : Entry point, used to display the installed packages.

system/packages/test.sls

{% from "system/packages/map.jinja" import packages with context %}
{%- set wanted_packages = packages.pkgs.wanted %}

print_variable:
  cmd.run:
    - name : echo {{ wanted_packages }} > /tmp/list_package.txt

system/packages/map.jinja :

{%- import_yaml 'system/packages/pkgs-base.yaml' as defaults %}
{%- import_yaml 'system/packages/pkgs-filterby-osfinger.yaml' as osfingermap %}

{%- set packages = salt['grains.filter_by'](
  defaults,
  merge = salt['grains.filter_by'](
    osfingermap,
    grain='osfinger'),
  base='packages')
%}

system/packages/pkgs-base.yaml

# -*- coding: utf-8 -*-
# vim: ft=yaml

packages:
  pkgs:
    wanted: ['rsync',
      'pigz',
      'redhat-lsb-core',
      'redhat-lsb',
      'dos2unix',
      'rng-tools',
      'zip',
      'unzip',
      'ksh']

system/packages/pkgs-filterby-osfinger.yaml

# -*- coding: utf-8 -*-  
# vim: ft=yaml  
  
CentOS Linux-7:  
  pkgs:  
    wanted: ['python36-lxml',  
      'pyOpenSSL']  
  
CentOS Linux-8:  
  pkgs:  
    wanted: ['python3-lxml',  
      'python3-pyOpenSSL',  
      'policycoreutils-python-utils',  
      'cifs-utils']

My actual grains osfinger is "CentOS Linux-8". I call the print on my minion with : salt-call state.sls system.packages.test

Only the osfinger packages are displayed:

----------
          ID: print_variable
    Function: cmd.run
        Name: echo ['python3-lxml', 'python3-pyOpenSSL', 'policycoreutils-python-utils', 'cifs-utils'] > /tmp/list_package.txt
      Result: True
     Comment: Command "echo ['python3-lxml', 'python3-pyOpenSSL', 'policycoreutils-python-utils', 'cifs-utils'] > /tmp/list_package.txt" run

If I remove the merge part on map.jinja and the defaults packages are now displayed.


Solution

  • grains.filter_by doesn't merge lists, only the dictionaries.

    What you want is something like:

    {% import_yaml "system/packages/pkgs-base.yaml" as defaults %}
    {% import_yaml "system/packages/pkgs-filterby-osfinger.yaml" as osfingermap %}
    
    {% set packages = salt["defaults.update"](
        salt["grains.filter_by"](osfingermap, grain="osfinger"),
        defaults
    ) %}
    

    Or just separate them out completely and have states like:

    install common dependencies:
      pkg.installed:
        - pkgs:
          - rsync
          - pigz
          - redhat-lsb-core
          - redhat-lsb
          - dos2unix
          - rng-tools
          - zip
          - unzip
          - ksh
    
    install os-specific dependencies:
      pkg.installed:
        - pkgs: {{ packages }}