2015-12-21 13 views
7

Eseguiamo diversi ambienti virtuali Python sui nostri minion gestiti da sale.SaltStack: Proprietà (valori calcolati) per i dati dei file SLS?

Il nome del sistema è costruito da questo schema:

project_customer_stage 

Esempio:

supercms_favoritcustomer_p 

I dati pilastro:

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

Per ogni virtualenv abbiamo un utente linux . Fino ad ora calcoliamo valori come "casa" in questo modo:

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

Ma è ridondante.

Come evitare di copiare e incollare {% set system_home = ...%}?

Io sono come la programmazione ad oggetti modo orientato funziona:

  • Si potrebbe definire una proprietà per la home-directory
  • Se avete bisogno di un diverso e directory-home in un caso particolare, allora si potrebbe creare una sottoclasse la classe base e sovrascrive il modo in cui la classe base funziona.

In Salt hai YAML e templating ... Entrambe le cose belle. Ma nel mio caso l'OOP sarebbe carino.

risposta

3

È inoltre possibile generare dinamicamente i dati del pilastro. Si consideri il seguente esempio per un file pilastro: i dati dei carichi di definizione

{% 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 %} 

Questo pilastro YAML da un file per il quale systems.yml Salt cercherà nella directory pillar_root. Questo file potrebbe assomigliare a questo (molto simile al tuo esempio iniziale):

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

Si noti che questo esempio calcola immobili come il nome del progetto e la directory home dell'utente in modo dinamico, a meno che non siano esplicitamente definite nel file di dati. Per questo, il Jinja default() filter viene utilizzato nella definizione del pilastro.

Usando questa definizione pilastro, si può semplicemente utilizzare name e home nelle definizioni di stato direttamente dai dati pilastro:

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

Inoltre, come a mio parere file SLS questi Jinja-pesanti ottenere un po 'difficile da leggere, si potrebbe prendere in considerazione il passaggio al file Python renderer per il file pilastro:

#!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} 
+0

Sono d'accordo con te: "questi file SLS pesanti di Jinja diventano un po 'difficili da leggere". Credo che userò un renderer python. Grazie. – guettli