Своды правил#

Свод правил (rulebook) – это файл формата YAML, содержащий список наборов правил (ruleset).

Структура типового свода правил показана на схеме:

../../_images/rulebook.svg

Свод правил содержит несколько наборов правил (ruleset). Каждый набор правил содержит сведения об источниках событий (source) и правила (rule). Каждое правило состоит из списка условий (conditions), выполнение которых приводит к запуску тех или иных действий (actions).

Пример файла, содержащего свод правил:

---
- name: Example ruleset 1
  hosts: all
  sources:
    - name: Source 1
      ansible.eda.url_check:
        urls:
          - https://example.com/heartbeat/
        delay: 10

  rules:
    - name: Rule 1
      condition: event.status == "down"
      action:
        run_job_template:
          name: "Reload server"
          organization: "Default"

- name: Example ruleset 2
  hosts: database
  sources:
    - name: PG Status
      ansible.eda.webhook:
        host: https://source.example.com/api/webhook/
        port: 443
        keyfile: /path/to/keyfile

  rules:
    - name: Rule 2
      conditinon:
        any:
          - event.payload.connections_free <= 10
          - event.payload.mem_free < 2048
      action:
        run_job_template:
          name: "Restart PostgreSQL server"
          organization: "Default"

Этот свод правил содержит два набора правил.

  • Example ruleset 1

    Состоит из источника «Source 1» и правила «Rule 1».

    Источник «Source 1» каждые 10 секунд проверяет код возврата при обращении к указанному URI. Если код возврата отличается от 200, либо его вовсе не удается получить за указанное время, контроллер EDA создает событие, в свойствах которого заполняет поле status значением down.

    Реакция на указанное событие описана в правиле «Rule 1». Оно проверяет поля status на равенство значению down. Если условие выполнено, EDA подключается к Automation Controller и запускает задание на основе шаблона Reload server, принадлежащего организации Default.

  • Example ruleset 2

    Состоит из источника «PG Status» и правила «Rule 2».

    Источник «PG Status» получает данные через веб-обработчик, отслеживающий обращения к точке доступа API https://source.example.com/api/webhook/. Содержимое ответа сохраняется в поле payload.

    Правило «Rule 2» проверяет выполнение двух условий:

    • значение payload.connections_free меньше или равно 10 (исчерпание свободных подключений к серверу PostgreSQL);

    • значение payload.mem_free меньше 2048 (исчерпание свободной оперативной памяти).

    Если выполняется хотя бы одно из указанных условий, контроллер EDA подключается к Automation Controller и запускает задание на основе шаблона Restart PostgreSQL server, принадлежащего организации Default.

Важно

Предполагается, что контроллер EDA интегрирован с Automation Controller, в котором существуют организация Default и принадлежащие ей шаблоны заданий Reload server и Restart PostgreSQL server.

Наборы правил#

Каждый набор правил содержит следующие поля:

  • name – уникальное название набора правил.

    Это поле обязательно для заполнения.

    Важно

    Названия наборов правил должны быть уникальны на уровне свода. Это необходимо для обмена сообщениями между наборами правил во время их выполнения.

    Каждый набор правил выполняется в отдельной сессии механизма исполнения правил. События и факты хранятся отдельно для каждого набора правил правил. Во время выполнения набор правил может отправить событие или факт сам себе или другому набору правил из этого же свода правил.

  • sources – список источников событий.

    Это поле обязательно для заполнения.

  • rules – список правил.

    Это поле обязательно для заполнения.

  • hosts – список узлов, к которым применяются действия, описанные в блоке rules.action или rules.actions.

    Это поле обязательно для заполнения.

  • gather_facts – сбор фактов Ansible при запуске правила.

    Контроллер EDA собирает факты Ansible в момент запуска свода правил. Собранные данные сохраняются и могут быть использованы в соответствующих выражениях.

    Данные о каждом узле хранятся отдельно. Название узла хранится в свойстве fact.meta.hosts, например:

    - name: Ruleset example
      hosts: all
      gather_facts: true
      sources:
        # ...
      rules:
        - name: Host specific rule
          condition:
            all:
              - fact.ansible_os_family == "linux"
              - fact.meta.hosts == "node1.example.com"
              - event.i == 4
      # ...
    

    По умолчанию факты не собираются, то есть gather_facts: false.

  • default_events_ttl – длительность периода, в течение которого хранятся данные о частично наступивших событиях.

    Значение этого поля задается в следующем формате:

    <count> <unit>
    

    Здесь:

    • <count> – количество;

    • <unit> – единица измерения:

      • seconds – секунды;

      • minutes – минуты;

      • hours – часы;

      • days – дни.

    Значение по умолчанию – 2 hours (2 часа).

  • execution_strategy – стратегия выполнения действий:

    • sequential – действия выполняются в порядке очереди;

    • parallell – действия выполняются параллельно.

    Значение по умолчанию – sequential.

Набор правил должен содержать хотя бы одно расширение для работы с источниками событий. Настройки каждого расширения должны быть указаны после типа расширения. Расширение источника может быть настроено с помощью фильтра событий, который позволяет изменить данные перед передачей их на исполнение правил. Утилита ansible-rulebook запускает расширение источника и исполняет его в фоновом режиме, помещая события в очередь исполнения. Когда расширение источника завершает работу, оно автоматически создает соответствующее действие и прерывает выполнение набора правил. Это, в свою очередь, приводит к завершению работы ansible-rulebook.

Набор правил должен содержать хотя бы одно правило. Контроллер EDA выполняет все необходимые проверки для правил, основанных на входящих событиях. Если условия в правиле выполняются, контроллер EDA выполняет соответствующие действия.

Действием может быть запуск playbook или модулей, возбуждение другого события или создание факта в том же самом или другом наборе правил.

Исполнение набора правил завершается в следующих случаях:

  • расширение источника создает событие завершения работы;

  • одно из выполненных правил создает событие завершения работы.

Распространение#

Рекомендуется распространять своды правил в составе коллекций. В этом случае свод правил должен быть размещен в каталоге extensions/eda/rulebooks, а ссылка на него указана в аргументах CLI.

Источники#

Для обработки событий, поступающих из различных типов источников, контроллер EDA использует расширения. Эти расширения могут храниться локально, однако, более эффективно их распространение в составе коллекций.

Коллекция ansible.eda предоставляет следующие расширения для работы с различными типами источников:

  • alertmanager – получение событий через веб-обработчики Prometheus Alertmanager;

  • azure_service_bus – получение событий от служб Microsoft Azure;

  • file_watch – отслеживание состояния файловой системы;

  • file – загрузка фактов из файла YAML и их обновление при изменении содержимого файла;

  • kafka – обработка событий, хранящихся в топиках Apache Kafka;

  • range – генерация событий с индексами из указанного диапазона;

  • tick – генерация событий с индексами, которые задает бесконечно увеличивающийся счетчик;

  • url_check – периодическая проверка HTTP-статусов указанных URL;

  • webhook – использование веб-обработчиков для получения сведений о событиях.

Примечание

Как правило, типы источников tick, file и range используются при разработке и тестировании.

Пример использования источника ansible.eda.webhook#
- name: Listen port 5000 with webhook
  hosts: all
  sources:
    - ansible.eda.webhook:
        host: 192.168.56.1
        port: 5000
  # ...

Независимо от типа используемого расширения, полученные им данные передаются в правила через объект event.

Особенности использования различных типов источников описаны в справочнике.

Правила#

Каждое правило содержит следующие поля:

  • name – название правила.

    Это поле обязательно для заполнения.

    Важно

    Названия правил должны быть уникальны на уровне свода.

    При формировании названий правил допускается использовать шаблонизатор Jinja2.

  • condition – условие или список условий, выполнение которых считается наступлением события.

    Это поле обязательно для заполнения.

  • action – действие, которое должно быть выполнено при наступлении события, например:

    rules:
      - name: Rule with one action
        condition: event.outage == true
        action:
          run_job_templtae:
            name: "Job template example"
            organization: "Default"
    
  • actions – список действий, которые должны быть выполнены при наступлении события, например:

    rules:
      - name: Rule with multiple actions
        condition: event.outage == true
        actions:
          - run_playbook:
              name: playbook.yml
          - print_event:
              pretty: true
    
  • enabled – разрешение на использование правила.

    Значение по умолчанию – true (использование правила разрешено).

Особенности использования действий описаны в справочнике.

Условия#

Условие – выражение, результатом вычисления которого могут быть только логические значения true (условие выполнено) и false (условие не выполнено).

Условие может содержать:

  • одно условие:

    condition: event.host == 'localhost'
    
  • несколько условий, которые должны быть выполнены одновременно:

    condition:
      all:
        - event.target_os == "linux"
        - event.tracking_id == 123
    
  • несколько условий, из которых должно быть выполнено хотя бы одно:

    condition:
      any:
        - event.target_os == "linux"
        - event.target_os == "windows"
    
  • несколько условий, из которых хотя бы одно не выполняется:

    condition:
      not_all:
        - event.target_os == "linux"
        - event.target_os == "freebsd"
    

Условия могут использовать информацию из следующих источников:

  • полученное событие;

  • событие, сохранное в правиле ранее;

  • долговременные факты о системе;

  • переменные, переданные пользователем при запуске правила.

Для установки значений переменных или получения данных используйте следующие префиксы:

  • event – для доступа к данным текущего события;

  • events – для установки значений переменных и доступа к данным внутри правила;

  • fact – для доступа к данным, заданным с помощью set_facts в своде правил;

  • facts – для установки значений переменных и доступа к данным внутри правила;

  • vars – для доступа к значениям переменных, заданных в опциях CLI --vars и --env-vars.

    Важно

    Выражения не могут содержать замены с использованием шаблонов Jinja при доступе к переменным, переданным в опциях CLI, так как при этом теряется информация о типе данных, и контроллер EDA не может обработать условие. Вместо этого используйте поле vars для доступа к данным, переданным в опциях CLI.

В одном выражении нельзя использовать данные из fact и event. Вместо этого необходимо предварительно передать данные в facts с помощью set_fact, например:

---
rules:
  - name: Using fact and event together
    condition:
      all:
        - facts.storage << fact.custom.free_space is defined
        - event.space <= facts.storage.custom.free_space

Обращение к нужным полям может быть записано через точку (точечная нотация) или в квадратных скобках (скобочная нотация). Следующие два правила идентичны:

---
rules:
  - name: Rule with dot notation
    condition: event.data.nested == true
    action:
      debug:

  - name: Rule with bracket notation
    condition: event.data["nested"] == true
    action:
      debug:

Использование скобочной нотации рекомендуется для случаев, когда название поля содержит точки и другие специальные символы, например:

---
rules:
  - name: Rule for special characters field
    condition: event.resource.metadata.labels["app.kubernetes.io/name"] == "example"
    action:
      debug

Также скобочная нотация может быть использована для обращения к элементам списков. Нумерация элементов списка при этом начинается с нуля:

---
rules:
  - name: Rule for checking second list item
    condition: event.packages[1] == "2-st package"
    action:
      debug:

Отрицательные значения позволяют обращаться к элементам списка, начиная отсчет с конца, как это принято в Python.

Типы данных#

Возможно использование следующих типов данных:

  • целые числа (integers);

  • строки (strings);

  • логические значения (booleans);

  • вещественные числа (float), записанные в точечной или научной нотации, например, 10.5 или 105E-1;

  • null.

Операторы#

Операторы используются для создания логических выражений. Для некоторых операторов, работающих со строками, поддерживается флаг <ignorecase>. Он управляет игнорированием регистра символов при поиске и по умолчанию равен true (регистр символов не имеет значения).

При описании выражений допускается использовать следующие операторы:

  • == – равенство строк, чисел или логических значений.

  • != – неравенство строк, чисел или логических значений.

  • > – число слева больше числа справа.

  • < – число слева меньше числа справа.

  • >= – число слева больше или равно числу справа.

  • <= – число слева меньше или равно числу справа.

  • + – сложение чисел.

  • - – разность чисел.

  • * – умножение чисел.

  • and – логическое «и», используется для создания сложных выражений.

  • or – не исключающее «или», используется для создания сложных выражений.

  • in – проверка присутствия значения из левой части выражения в списке из правой части.

  • not in – проверка отсутствия значения из левой части выражения в списке из правой части.

  • contains – проверка присутствия в списке из левой части выражения значения, указанного в правой части.

  • not contains – проверка отсутствия в списке из левой части выражения значения, указанного в правой части.

  • is defined – проверка существования переменной.

  • is not defined – проверка отсутствия переменной.

  • is match(<pattern>, <ignorecase>) – проверка начала строки на совпадение с указанным шаблоном <pattern>.

    Допускается использование регулярных выражений.

  • is not match(<pattern>, <ignorecase>) – проверка начала строки на несовпадение с указанным шаблоном <pattern>.

    Допускается использование регулярных выражений.

  • is search(<pattern>, <ignorecase>) – проверка строки на наличие подстроки, удовлетворяющей шаблону <pattern>.

    Допускается использование регулярных выражений.

  • is not search(<pattern>, <ignorecase>) – проверка строки на отсутствие подстроки, удовлетворяющей шаблону <pattern>.

    Допускается использование регулярных выражений.

  • is regex(<regexp>, <ignorecase>) – проверка строки на наличие подстроки, удовлетворяющей регулярному выражению <regexp>.

  • is not regex(<regexp>, <ignorecase>) – проверка строки на отсутствие подстроки, удовлетворяющей регулярному выражению <regexp>.

  • is select(<operator>, <value>) – проверка наличия в списке из левой части выражения хотя бы одного элемента, для которого выполняется условие, состоящее из оператора <operator> и значения <value>.

  • is not select(<operator>, <value> – проверка отсутствия в списке из левой части выражения элементов, для которых выполняется условие, состоящее из оператора <operator> и значения <value>.

  • is selectattr(<key>, <operator>, <value>) – проверка наличия в списке из левой части выражения хотя бы одного элемента, у которого для значения поля <key> выполняется условие, состоящее из оператора <operator> и значения <value>.

  • is not selectattr(<key>, <operator>, <value>) – проверка отсутствия в списке из левой части выражения элементов, у которых для значения поля <key> выполняется условие, состоящее из оператора <operator> и значения <value>.

  • << – оператор присваивания, используемый для сохранения событий или фактов.

  • not – оператор инвертирования логического выражения.

Примеры#

В этом примере рассматривается несложный свод правил:

Пример свода правил#
---
- name: Rulebook example
  hosts: all
  sources:
    - ansible.eda.url_check:
        urls:
          - https://192.168.56.1/api/heartbeat/
        delay: 10
        verify_ssl: false

  rules:
    - name: Check headers status
      condition: event.url_check.status == "down"
      action:
        run_job_template:
          name: "Restart service"
          organization: "Default"

Для подключения к источнику используется расширение ansible.eda.url_check со следующими параметрами:

  • URI источника – https:/192.168.56.1/api/heartbeat/;

  • периодичность проверки – каждые 10 секунд;

  • проверка сертификата SSL – выключена.

Расширение ansible.eda.url_check добавляет в объект event свойство status, которое может принимать только два значения:

  • up – если HTTP-код ответа равен 200 при обращении к указанному URI;

  • down – во всех остальных случаях, в том числе при отсутствии какого-либо ответа со стороны источника.

В правиле Check header status выполняется проверка статуса. Если он равен down, значит, нужный URI недоступен. Для восстановления работоспособности сервера, на котором он размещен, контроллера EDA подключается к Automation Controller и запускает задание на основе шаблона Restart service, принадлежащего организации Default.