SaltStack: Properties (computed values) for data from SLS files?

We run several Python virtual environments on our minions managed by salt.

The name of the system is build by this schema:

project_customer_stage

Example:

supercms_favoritcustomer_p

The pillar data:

systems:
  - customer: favoritcustomer
    project: supercms
    stage: p
  - customer: favoritcustomer
    project: supercms
    stage: q 

For every virtualenv we have one linux user. Up to now we compute values like "home" like this:

{% for system in pillar.systems %}
  {% set system_name = system.project + '_' + system.customer + '_' + system.stage %}
  {% set system_home = '/home/' + system_name %}
  ...

But it is redundant.

How could we avoid copy+pasting {% set system_home = ...%} ?

I am like the way object oriented programming works:

  • You could define a property for the home-directory
  • If you need a different home-directory in a special case, then you could subclass the base class and overwrite the way the base class works.
  • In Salt you have YAML and templating ... Both nice things. But in my case OOP would be nice.


    You can also generate pillar data dynamically. Consider the following example for a pillar file:

    {% import_yaml "systems.yml" as systems %}
    
    systems:
    {% for system in systems %}
    {% set name = system['name'] | default(system.project + '_' + system.customer + '_' + system.stage) %}
    {% set home = system['home'] | default('/home/' + name) %}
      - name: {{ name }}
        customer: {{ system['customer'] }}
        project: {{ system['project'] }}
        stage: {{ system['stage'] }}
        home: {{ home }}
    {% endfor %}
    

    This pillar definition loads YAML data from a systems.yml file for which Salt will look in your pillar_root directory. This file might look like this (very similar to your initial example):

    - customer: smith
      project: cms
      stage: p
    - customer: jones
      project: shop
      stage: p
      name: jones_webshop_p  # <-- alternate name here!
    

    Note that this example computes properties like the project name and the user's home directory dynamically, unless they are explicitly defined in your data file. For this, the Jinja default() filter is used in the pillar definition.

    Using this pillar definition, you can simply use name and home in your state definitions directly from the pillar data:

    {% for system in salt['pillar.get']('systems') %}
    {{ system.home }}:
      file.directory
    {% endfor %}
    

    Additionally , as in my opinion these Jinja-heavy SLS files get a little hard to read, you might consider switching to the Python renderer for your pillar file:

    #!py
    
    import yaml
    
    def run():
      systems = []
      with open('systems.yml', 'r') as f:
        data = yaml.safe_load(f)
    
        for system in data:
          if not 'name' in system:
            system['name'] = "%s_%s_%s" % (system['project'], system['customer'], system['stage'])
    
          if not 'home' in system:
            system['home'] = "/home/%s" % name
    
          systems.append(system)
    
      return {"systems": systems}
    
    链接地址: http://www.djcxy.com/p/31266.html

    上一篇: Visual Basic编辑器Excel 2016中的边距

    下一篇: SaltStack:来自SLS文件的数据的属性(计算值)?