Своды правил#
Свод правил (rulebook) – это файл формата YAML, содержащий список наборов правил (ruleset).
Структура типового свода правил показана на схеме:
Свод правил содержит несколько наборов правил (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
– действие, которое должно быть выполнено при наступлении события, например:actions
– список действий, которые должны быть выполнены при наступлении события, например: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.