SaltStack: свойства (вычисленные значения) для данных из файлов SLS?

Мы запускаем несколько виртуальных сред Python на наших миньонах, управляемых солью.

Название системы построено по этой схеме:

project_customer_stage

Пример:

supercms_favoritcustomer_p

Данные столба:

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

Для каждого virtualenv у нас есть один пользователь Linux. До сих пор мы вычисляли значения типа «дом» следующим образом:

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

Но это избыточно.

Как мы можем избежать копирования+вставки {% set system_home = ...%}?

Мне нравится, как работает объектно-ориентированное программирование:

  • Вы можете определить свойство для домашнего каталога
  • Если вам нужен другой домашний каталог в особом случае, вы можете подклассировать базовый класс и перезаписать способ работы базового класса.

В Salt есть YAML и шаблоны... И то, и другое приятно. Но в моем случае ООП было бы неплохо.


person guettli    schedule 21.12.2015    source источник


Ответы (1)


Вы также можете динамически генерировать данные столба. Рассмотрим следующий пример файла столбца:

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

Это определение столбца загружает данные YAML из файла systems.yml, который Salt будет искать в вашем каталоге pillar_root. Этот файл может выглядеть так (очень похоже на ваш первоначальный пример):

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

Обратите внимание, что в этом примере такие свойства, как имя проекта и домашний каталог пользователя, вычисляются динамически, если только они не определены явно в вашем файле данных. Для этого в определении столба используется default() filter Jinja.

Используя это определение опоры, вы можете просто использовать name и home в своих определениях состояний непосредственно из данных опоры:

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

Кроме того, поскольку, по моему мнению, эти SLS-файлы с большим количеством Jinja становятся немного трудными для чтения, вы можете подумать о переходе на рендерер Python для вашего файла столба:

#!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}
person helmbert    schedule 27.12.2015
comment
Я согласен с вами: эти SLS-файлы с большим количеством Jinja становятся немного трудными для чтения. Думаю, я буду использовать средство визуализации Python. Спасибо. - person guettli; 30.12.2015