Использование фильтров для обработки данных
Фильтры позволяют преобразовывать данные JSON в YAML, разделять URL-адрес для извлечения имени хоста, получить хеш SHA1 строки, складывать или умножать целые числа и многое другое. Вы можете использовать специфичные для Ansible фильтры, документированные здесь, для обработки данных или использовать стандартные фильтры, поставляемые с Jinja2 — см. список встроенных фильтров в официальной документации шаблонов Jinja2. Вы также можете использовать методы Python для преобразования данных. Вы можете создавать пользовательские фильтры Ansible в виде плагинов, хотя мы обычно приветствуем новые фильтры в репозитории ansible-base, чтобы все могли их использовать.
Поскольку шаблонизация происходит на контроллере Ansible, а не на целевом хосте, фильтры выполняются на контроллере и преобразуют данные локально.
- Определение различных значений для true/false/null (тернарный)
- Управление списками переменных
- Выбор из множеств или списков (теория множеств)
- Вычисление чисел (математика)
- Шифрование и проверка целостности строк и паролей
- Обработка строк
- Управление UUID
- Работа с датами и временем
- Получение имён ресурсов Kubernetes
Обработка неопределённых переменных
Фильтры могут помочь в управлении отсутствующими или неопределёнными переменными, предоставляя значения по умолчанию или делая некоторые переменные необязательными. Если вы настраиваете Ansible на игнорирование большинства неопределённых переменных, вы можете отметить некоторые переменные как требующие значений с помощью фильтра mandatory.
Установление значений по умолчанию
Вы можете установить значения по умолчанию для переменных непосредственно в своих шаблонах, используя фильтр Jinja2 ‘default’. Это часто более подходящий подход, чем пропуск, если переменная не определена:
{{ some_variable | default(5) }}
В приведенном примере, если переменная ‘some_variable’ не определена, Ansible использует значение по умолчанию 5 вместо того, чтобы генерировать ошибку «неопределённая переменная» и прекращать выполнение. Если вы работаете с ролью, вы также можете добавить defaults/main.yml для определения значений по умолчанию для переменных в вашей роли.
Начиная с версии 2.8, попытка доступа к атрибуту неопределённого значения в Jinja вернёт другое неопределённое значение, вместо немедленного вывода ошибки. Это означает, что теперь вы можете просто использовать значение по умолчанию со вложенной структурой данных (другими словами, {{ foo.bar.baz | default('DEFAULT') }}), когда вы не знаете, определены ли промежуточные значения.
Если вы хотите использовать значение по умолчанию, когда переменные принимают значение ложь или пустую строку, вам нужно установить второй параметр на true:
{{ lookup('env', 'MY_USER') | default('admin', true) }}
Делаем переменные необязательными
По умолчанию Ansible требует значений для всех переменных в выражении шаблона. Однако вы можете сделать определённые переменные необязательными. Например, вы можете использовать системное значение по умолчанию для некоторых элементов и контролировать значение для других. Для того, чтобы сделать переменную необязательной, установите значение по умолчанию для специальной переменной omit:
- name: Touch files with an optional mode
ansible.builtin.file:
dest: "{{ item.path }}"
state: touch
mode: "{{ item.mode | default(omit) }}"
loop:
- path: /tmp/foo
- path: /tmp/bar
- path: /tmp/baz
mode: "0444"
В этом примере, режим по умолчанию для файлов /tmp/foo и /tmp/bar определяется маской umask системы. Ansible не отправляет значение для mode. Только третий файл, /tmp/baz, получает опцию mode=0444.
Примечание
Если вы «цепочкой» добавляете дополнительные фильтры после фильтра default(omit), вам следует сделать что-то подобное: "{{ foo | default(None) | some_filter or omit }}". В этом примере значение по умолчанию None (Python null) приведёт к ошибкам в последующих фильтрах, которые вызовут часть логики or omit. Использование omit таким образом очень специфично для последующих фильтров, поэтому будьте готовы к некоторым экспериментам, если вы это сделаете.
Определение обязательных значений
Если вы настроили Ansible игнорировать неопределённые переменные, вы можете определить некоторые значения как обязательные. По умолчанию Ansible завершается ошибкой, если переменная в вашем плейбуке или команде не определена. Вы можете настроить Ansible разрешать неопределённые переменные, установив DEFAULT_UNDEFINED_VAR_BEHAVIOR на false. В этом случае вы можете потребовать определения некоторых переменных. Вы можете сделать это так:
{{ variable | mandatory }}
Значение переменной будет использоваться как есть, но оценка шаблона выведет ошибку, если она не определена.
Определение различных значений для true/false/null (тернарный)
Вы можете создать тест, затем определить одно значение для использования, когда тест возвращает true, и другое, когда тест возвращает false (новая функция в версии 1.9):
{{ (status == 'needs_restart') | ternary('restart', 'continue') }}
Кроме того, вы можете определить одно значение для true, одно значение для false и третье значение для null (новая функция в версии 2.8):
{{ enabled | ternary('no shutdown', 'shutdown', omit) }}
Управление типами данных
Возможно, вам понадобится узнать, изменить или установить тип данных переменной. Например, зарегистрированная переменная может содержать словарь, когда следующему заданию нужен список, или пользовательский запрос может вернуть строку, когда ваш плейбук требует булево значение. Используйте фильтры type_debug, dict2items и items2dict для управления типами данных. Вы также можете использовать сам тип данных для преобразования значения в определённый тип данных.
Определение типа данных
Новое в версии 2.3.
Если вы не уверены в базовом типе Python переменной, вы можете использовать фильтр type_debug для его отображения. Это полезно при отладке, когда вам нужен определённый тип переменной:
{{ myvar | type_debug }}
Преобразование словарей в списки
Новое в версии 2.6.
Используйте фильтр dict2items для преобразования словаря в список элементов, подходящих для циклов:
{{ dict | dict2items }}
Данные словаря (до применения фильтра dict2items):
tags: Application: payment Environment: dev
Данные списка (после применения фильтра dict2items):
- key: Application value: payment - key: Environment value: dev
Новое в версии 2.8.
Фильтр dict2items является обратным фильтру items2dict.
Если вы хотите настроить имена ключей, фильтр dict2items принимает 2 именованных аргумента. Передайте аргументы key_name и value_name для настройки имён ключей в выходном списке:
{{ files | dict2items(key_name='file', value_name='path') }}
Данные словаря (до применения фильтра dict2items):
files: users: /etc/passwd groups: /etc/group
Данные списка (после применения фильтра dict2items):
- file: users path: /etc/passwd - file: groups path: /etc/group
Преобразование списков в словари
Новое в версии 2.7.
Используйте фильтр items2dict для преобразования списка в словарь, сопоставляя содержимое в пары key: value:
{{ tags | items2dict }}
Данные списка (до применения фильтра items2dict):
tags:
- key: Application
value: payment
- key: Environment
value: dev
Данные словаря (после применения фильтра items2dict):
Application: payment Environment: dev
Фильтр items2dict является обратным фильтру dict2items.
Не все списки используют key для обозначения ключей и value для обозначения значений. Например:
fruits:
- fruit: apple
color: red
- fruit: pear
color: yellow
- fruit: grapefruit
color: yellow
В этом примере необходимо передать аргументы key_name и value_name для настройки преобразования. Например:
{{ tags | items2dict(key_name='fruit', value_name='color') }}
Если вы не передадите эти аргументы или не передадите правильные значения для вашего списка, вы увидите KeyError: key или KeyError: my_typo.
Принудительное задание типа данных
Вы можете преобразовывать значения в определённые типы. Например, если вы ожидаете ввод “True” из vars_prompt и хотите, чтобы Ansible распознал его как булево значение, а не строку:
- debug: msg: test when: some_string_value | bool
Если вы хотите выполнить математическое сравнение с фактом и хотите, чтобы Ansible распознал его как целое число, а не строку:
- shell: echo "only on Red Hat 6, derivatives, and later" when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release'] | int >= 6
Новое в версии 1.6.
Форматирование данных: YAML и JSON
Вы можете преобразовать структуру данных в шаблоне в формат JSON или YAML с параметрами форматирования, отступов и загрузки данных. Базовые фильтры иногда полезны для отладки:
{{ some_variable | to_json }}
{{ some_variable | to_yaml }}
Для удобочитаемого вывода можно использовать:
{{ some_variable | to_nice_json }}
{{ some_variable | to_nice_yaml }}
Вы можете изменить отступы для любого из форматов:
{{ some_variable | to_nice_json(indent=2) }}
{{ some_variable | to_nice_yaml(indent=8) }}
Фильтры to_yaml и to_nice_yaml используют библиотеку PyYAML, которая имеет лимит длины строки по умолчанию в 80 символов. Это приводит к неожиданному переносу строки после 80-го символа (если после 80-го символа есть пробел). Чтобы избежать такого поведения и создать длинные строки, используйте параметр width. Необходимо использовать жёстко заданное число для определения ширины, вместо конструкции, подобной float("inf"), так как фильтр не поддерживает проксирование функций Python. Например:
{{ some_variable | to_yaml(indent=8, width=1337) }}
{{ some_variable | to_nice_yaml(indent=8, width=1337) }}
Фильтр поддерживает передачу других параметров YAML. Полный список см. в документации PyYAML.
Если вы считываете уже отформатированные данные:
{{ some_variable | from_json }}
{{ some_variable | from_yaml }}
например:
tasks:
- name: Register JSON output as a variable
ansible.builtin.shell: cat /some/path/to/file.json
register: result
- name: Set a variable
ansible.builtin.set_fact:
myvar: "{{ result.stdout | from_json }}"
Фильтр to_json и поддержка Unicode
По умолчанию to_json и to_nice_json преобразуют полученные данные в ASCII, поэтому:
{{ 'München'| to_json }}
возвратит:
'M\u00fcnchen'
Чтобы сохранить символы Unicode, передайте параметр ensure_ascii=False в фильтр:
{{ 'München'| to_json(ensure_ascii=False) }}
'München'
Новое в версии 2.7.
Для разбора многодокументных строк YAML предоставляется фильтр from_yaml_all. Фильтр from_yaml_all вернёт генератор обработанных документов YAML.
например:
tasks:
- name: Register a file content as a variable
ansible.builtin.shell: cat /some/path/to/multidoc-file.yaml
register: result
- name: Print the transformed variable
ansible.builtin.debug:
msg: '{{ item }}'
loop: '{{ result.stdout | from_yaml_all | list }}'
Объединение и выбор данных
Вы можете объединять данные из нескольких источников и типов, и выбирать значения из больших структур данных, обеспечивая точный контроль над сложными данными.
Объединение элементов из нескольких списков: zip и zip_longest
Новое в версии 2.3.
Чтобы получить список, объединяющий элементы других списков, используйте zip:
- name: Give me list combo of two lists
ansible.builtin.debug:
msg: "{{ [1,2,3,4,5] | zip(['a','b','c','d','e','f']) | list }}"
- name: Give me shortest combo of two lists
ansible.builtin.debug:
msg: "{{ [1,2,3] | zip(['a','b','c','d','e','f']) | list }}"
Чтобы всегда использовать все списки, используйте zip_longest:
- name: Give me longest combo of three lists , fill with X
ansible.builtin.debug:
msg: "{{ [1,2,3] | zip_longest(['a','b','c','d','e','f'], [21, 22, 23], fillvalue='X') | list }}"
Аналогично выводу фильтра items2dict, упомянутого выше, эти фильтры можно использовать для построения dict:
{{ dict(keys_list | zip(values_list)) }}
Данные списка (до применения фильтра zip):
keys_list: - one - two values_list: - apple - orange
Данные словаря (после применения фильтра zip):
one: apple two: orange
Объединение объектов и подэлементов
Новое в версии 2.7.
Фильтр subelements создаёт произведение объекта и значений подэлементов этого объекта, аналогично поиску subelements. Это позволяет указать отдельные подэлементы для использования в шаблоне. Например, это выражение:
{{ users | subelements('groups', skip_missing=True) }}
Данные до применения фильтра subelements:
users: - name: alice authorized: - /tmp/alice/onekey.pub - /tmp/alice/twokey.pub groups: - wheel - docker - name: bob authorized: - /tmp/bob/id_rsa.pub groups: - docker
Данные после применения фильтра subelements:
-
- name: alice
groups:
- wheel
- docker
authorized:
- /tmp/alice/onekey.pub
- /tmp/alice/twokey.pub
- wheel
-
- name: alice
groups:
- wheel
- docker
authorized:
- /tmp/alice/onekey.pub
- /tmp/alice/twokey.pub
- docker
-
- name: bob
authorized:
- /tmp/bob/id_rsa.pub
groups:
- docker
- docker
Вы можете использовать преобразованные данные с loop, чтобы итерироваться по одному и тому же подэлементу для нескольких объектов:
- name: Set authorized ssh key, extracting just that data from 'users'
ansible.posix.authorized_key:
user: "{{ item.0.name }}"
key: "{{ lookup('file', item.1) }}"
loop: "{{ users | subelements('authorized') }}"
Объединение хэшей/словарей
Новое в версии 2.0.
Фильтр combine позволяет объединять хэши. Например, следующее переопределит ключи в одном хэше:
{{ {'a':1, 'b':2} | combine({'b':3}) }}
Результирующий хэш будет:
{'a':1, 'b':3}
Фильтр также может принимать несколько аргументов для объединения:
{{ a | combine(b, c, d) }}
{{ [a, b, c, d] | combine }}
В этом случае ключи в d переопределят ключи в c, которые переопределят ключи в b и так далее.
Фильтр также принимает два необязательных параметра: recursive и list_merge.
- recursive
-
Логическое значение, по умолчанию
False. Необходимо ли рекурсивно объединять вложенные хэши. Примечание: Это не зависит от значенияhash_behaviourвansible.cfg. - list_merge
-
Строка, возможные значения:
replace(по умолчанию),keep,append,prepend,append_rpилиprepend_rp. Изменяет поведениеcombine, когда объединяемые хэши содержат массивы/списки.
default:
a:
x: default
y: default
b: default
c: default
patch:
a:
y: patch
z: patch
b: patch
Если recursive=False (по умолчанию), вложенные хэши не объединяются:
{{ default | combine(patch) }}
Это приведёт к:
a: y: patch z: patch b: patch c: default
Если recursive=True, рекурсивно объединяются вложенные хэши и их ключи:
{{ default | combine(patch, recursive=True) }}
Это приведёт к:
a: x: default y: patch z: patch b: patch c: default
Если list_merge='replace' (по умолчанию), массивы из правого хэша "заменяют" массивы в левом хэше:
default:
a:
- default
patch:
a:
- patch
{{ default | combine(patch) }}
Это приведёт к:
a: - patch
Если list_merge='keep', массивы из левого хэша сохранятся:
{{ default | combine(patch, list_merge='keep') }}
Это приведёт к:
a: - default
Если list_merge='append', массивы из правого хэша будут добавлены к массивам в левом хэше:
{{ default | combine(patch, list_merge='append') }}
Это приведёт к:
a: - default - patch
Если list_merge='prepend', массивы из правого хэша будут добавлены в начало массивов в левом хэше:
{{ default | combine(patch, list_merge='prepend') }}
Это приведёт к:
a: - patch - default
Если list_merge='append_rp', поведение аналогично append_rp, но элементы массивов из правого хэша добавляются в начало:
default:
a:
- 1
- 1
- 2
- 3
patch:
a:
- 3
- 4
- 5
- 5
{{ default | combine(patch, list_merge='append_rp') }}
Это приведёт к:
a: - 1 - 1 - 2 - 3 - 4 - 5 - 5
Если list_merge='prepend_rp', поведение аналогично append_rp, но элементы массивов из правого хэша добавляются в начало:
{{ default | combine(patch, list_merge='prepend_rp') }}
Это приведёт к:
a: - 3 - 4 - 5 - 5 - 1 - 1 - 2
recursive и list_merge могут использоваться вместе:
default:
a:
a':
x: default_value
y: default_value
list:
- default_value
b:
- 1
- 1
- 2
- 3
patch:
a:
a':
y: patch_value
z: patch_value
list:
- patch_value
b:
- 3
- 4
- 4
- key: value
{{ default | combine(patch, recursive=True, list_merge='append_rp') }}
Это приведёт к:
a:
a':
x: default_value
y: patch_value
z: patch_value
list:
- default_value
- patch_value
b:
- 1
- 1
- 2
- 3
- 4
- 4
- key: value
Выбор значений из массивов или хэштаблиц
Новое в версии 2.1.
Фильтр extract используется для сопоставления списка индексов со списком значений из контейнера (хэша или массива):
{{ [0,2] | map('extract', ['x','y','z']) | list }}
{{ ['x','y'] | map('extract', {'x': 42, 'y': 31}) | list }}
Результаты вышеприведённых выражений будут:
['x', 'z'] [42, 31]
Фильтр может принимать ещё один аргумент:
{{ groups['x'] | map('extract', hostvars, 'ec2_ip_address') | list }}
Это берёт список хостов в группе ‘x’, ищет их в hostvars, а затем ищет ec2_ip_address результата. Конечный результат — список IP-адресов хостов в группе ‘x’.
Третий аргумент фильтра также может быть списком для рекурсивного поиска внутри контейнера:
{{ ['a'] | map('extract', b, ['x','y']) | list }}
Это вернёт список, содержащий значение b[‘a’][‘x’][‘y’].
Объединение списков
Этот набор фильтров возвращает список объединённых списков.
Перестановки
Чтобы получить перестановки списка:
- name: Give me largest permutations (order matters)
ansible.builtin.debug:
msg: "{{ [1,2,3,4,5] | permutations | list }}"
- name: Give me permutations of sets of three
ansible.builtin.debug:
msg: "{{ [1,2,3,4,5] | permutations(3) | list }}"
Сочетания
Сочетания всегда требуют размера множества:
- name: Give me combinations for sets of two
ansible.builtin.debug:
msg: "{{ [1,2,3,4,5] | combinations(2) | list }}"
Также см. Объединение элементов из нескольких списков: zip и zip_longest
products
Фильтр product возвращает декартово произведение входных итерируемых объектов. Это примерно эквивалентно вложенным циклам for в выражении генератора.
Например:
- name: Generate multiple hostnames
ansible.builtin.debug:
msg: "{{ ['foo', 'bar'] | product(['com']) | map('join', '.') | join(',') }}"
Это приведет к:
{ "msg": "foo.com,bar.com" }
Выбор данных JSON: запросы JSON
Для выбора одного элемента или подмножества данных из сложной структуры данных в формате JSON (например, Ansible facts) используйте фильтр json_query. Фильтр json_query позволяет вам запросить сложную структуру JSON и перебирать ее с помощью цикла.
Примечание
Этот фильтр переместился в коллекцию community.general. Следуйте инструкциям по установке, чтобы установить эту коллекцию.
Примечание
Перед использованием этого фильтра необходимо вручную установить зависимость jmespath на контроллере Ansible. Этот фильтр построен на основе jmespath, и вы можете использовать тот же синтаксис. Примеры см. в примерах jmespath.
Рассмотрим такую структуру данных:
{
"domain_definition": {
"domain": {
"cluster": [
{
"name": "cluster1"
},
{
"name": "cluster2"
}
],
"server": [
{
"name": "server11",
"cluster": "cluster1",
"port": "8080"
},
{
"name": "server12",
"cluster": "cluster1",
"port": "8090"
},
{
"name": "server21",
"cluster": "cluster2",
"port": "9080"
},
{
"name": "server22",
"cluster": "cluster2",
"port": "9090"
}
],
"library": [
{
"name": "lib1",
"target": "cluster1"
},
{
"name": "lib2",
"target": "cluster2"
}
]
}
}
}
Чтобы извлечь все кластеры из этой структуры, вы можете использовать следующий запрос:
- name: Display all cluster names
ansible.builtin.debug:
var: item
loop: "{{ domain_definition | community.general.json_query('domain.cluster[*].name') }}"
Чтобы извлечь все имена серверов:
- name: Display all server names
ansible.builtin.debug:
var: item
loop: "{{ domain_definition | community.general.json_query('domain.server[*].name') }}"
Чтобы извлечь порты из cluster1:
- name: Display all ports from cluster1
ansible.builtin.debug:
var: item
loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}"
vars:
server_name_cluster1_query: "domain.server[?cluster=='cluster1'].port"
Примечание
Можно использовать переменную, чтобы сделать запрос более читабельным.
Чтобы вывести порты из cluster1 в строке, разделенной запятыми:
- name: Display all ports from cluster1 as a string
ansible.builtin.debug:
msg: "{{ domain_definition | community.general.json_query('domain.server[?cluster==`cluster1`].port') | join(', ') }}"
Примечание
В примере выше использование обратных кавычек для литералов предотвращает экранирование кавычек и сохраняет удобочитаемость.
Можно использовать YAML экранирование одинарных кавычек:
- name: Display all ports from cluster1
ansible.builtin.debug:
var: item
loop: "{{ domain_definition | community.general.json_query('domain.server[?cluster==''cluster1''].port') }}"
Примечание
Экранирование одинарных кавычек внутри одинарных кавычек в YAML выполняется путем удвоения одинарной кавычки.
Чтобы получить хэш-таблицу со всеми портами и именами кластера:
- name: Display all server ports and names from cluster1
ansible.builtin.debug:
var: item
loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}"
vars:
server_name_cluster1_query: "domain.server[?cluster=='cluster2'].{name: name, port: port}"
Чтобы извлечь порты из всех кластеров с именем, начинающимся с «server1»:
- name: Display all ports from cluster1
ansible.builtin.debug:
msg: "{{ domain_definition | to_json | from_json | community.general.json_query(server_name_query) }}"
vars:
server_name_query: "domain.server[?starts_with(name,'server1')].port"
Чтобы извлечь порты из всех кластеров с именем, содержащим «server1»:
- name: Display all ports from cluster1
ansible.builtin.debug:
msg: "{{ domain_definition | to_json | from_json | community.general.json_query(server_name_query) }}"
vars:
server_name_query: "domain.server[?contains(name,'server1')].port"
Примечание
при использовании starts_with и contains, необходимо использовать фильтр `` to_json | from_json `` для правильного парсинга структуры данных.
Генерация случайных данных
Когда вам нужно случайное значение, используйте один из этих фильтров.
Случайные MAC-адреса
Новое в версии 2.6.
Этот фильтр можно использовать для генерации случайного MAC-адреса из строкового префикса.
Примечание
Этот фильтр переместился в коллекцию community.general. Следуйте инструкциям по установке, чтобы установить эту коллекцию.
Чтобы получить случайный MAC-адрес из строкового префикса, начинающегося с ‘52:54:00’:
"{{ '52:54:00' | community.general.random_mac }}"
# => '52:54:00:ef:1c:03'
Обратите внимание, что если с префиксной строкой что-то не так, фильтр выдаст ошибку.
Новое в версии 2.9.
Начиная с версии Ansible 2.9, вы также можете инициализировать генератор случайных чисел из начального значения, чтобы создавать случайные, но идемпотентные MAC-адреса:
"{{ '52:54:00' | community.general.random_mac(seed=inventory_hostname) }}"
Случайные элементы или числа
Фильтр random в Ansible является расширением стандартного фильтра Jinja2 random и может использоваться для возвращения случайного элемента из последовательности элементов или генерации случайного числа в заданном диапазоне.
Чтобы получить случайный элемент из списка:
"{{ ['a','b','c'] | random }}"
# => 'c'
Чтобы получить случайное число от 0 до указанного числа:
"{{ 60 | random }} * * * * root /script/from/cron"
# => '21 * * * * root /script/from/cron'
Чтобы получить случайное число от 0 до 100 с шагом 10:
{{ 101 | random(step=10) }}
# => 70
Чтобы получить случайное число от 1 до 100 с шагом 10:
{{ 101 | random(1, 10) }}
# => 31
{{ 101 | random(start=1, step=10) }}
# => 51
Можно инициализировать генератор случайных чисел из начального значения, чтобы создавать случайные, но идемпотентные числа:
"{{ 60 | random(seed=inventory_hostname) }} * * * * root /script/from/cron"
Перемешивание списка
Фильтр shuffle случайным образом изменяет существующий список, предоставляя другой порядок при каждом вызове.
Чтобы получить случайный список из существующего списка:
{{ ['a','b','c'] | shuffle }}
# => ['c','a','b']
{{ ['a','b','c'] | shuffle }}
# => ['b','c','a']
Можно инициализировать генератор перемешивания из начального значения, чтобы получить случайный, но идемпотентный порядок:
{{ ['a','b','c'] | shuffle(seed=inventory_hostname) }}
# => ['b','a','c']
Фильтр перемешивания возвращает список, когда это возможно. Если вы используете его с элементом, не являющимся «списком», фильтр ничего не делает.
Управление переменными списков
Вы можете искать минимальное или максимальное значение в списке или выравнивать многоуровневый список.
Чтобы получить минимальное значение из списка чисел:
{{ list1 | min }}
Новое в версии 2.11.
Чтобы получить минимальное значение в списке объектов:
{{ [{'val': 1}, {'val': 2}] | min(attribute='val') }}
Чтобы получить максимальное значение из списка чисел:
{{ [3, 4, 2] | max }}
Новое в версии 2.11.
Чтобы получить максимальное значение в списке объектов:
{{ [{'val': 1}, {'val': 2}] | max(attribute='val') }}
Новое в версии 2.5.
Выровнять список (то же, что делает поиск flatten):
{{ [3, [4, 2] ] | flatten }}
Выровнять только первый уровень списка (аналогично поиску items):
{{ [3, [4, [2]] ] | flatten(levels=1) }}
Новое в версии 2.11.
Сохранить нулевые значения в списке, по умолчанию выравнивание их удаляет.
{{ [3, None, [4, [2]] ] | flatten(levels=1, skip_nulls=False) }}
Выбор из множеств или списков (теория множеств)
Вы можете выбирать или объединять элементы из множеств или списков.
Новое в версии 1.4.
Чтобы получить уникальное множество из списка:
# list1: [1, 2, 5, 1, 3, 4, 10]
{{ list1 | unique }}
# => [1, 2, 5, 3, 4, 10]
Чтобы получить объединение двух списков:
# list1: [1, 2, 5, 1, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | union(list2) }}
# => [1, 2, 5, 1, 3, 4, 10, 11, 99]
Чтобы получить пересечение двух списков (уникальный список всех элементов в обоих):
# list1: [1, 2, 5, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | intersect(list2) }}
# => [1, 2, 5, 3, 4]
Чтобы получить разность двух списков (элементы в первом, которых нет во втором):
# list1: [1, 2, 5, 1, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | difference(list2) }}
# => [10]
Чтобы получить симметрическую разность двух списков (элементы, уникальные для каждого списка):
# list1: [1, 2, 5, 1, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | symmetric_difference(list2) }}
# => [10, 11, 99]
Вычисления с числами (математика)
Новое в версии 1.9.
Вы можете вычислять логарифмы, степени и корни чисел с помощью фильтров Ansible. Jinja2 предоставляет другие математические функции, такие как abs() и round().
Получить логарифм (по умолчанию по основанию e):
{{ myvar | log }}
Получить логарифм по основанию 10:
{{ myvar | log(10) }}
Получить степень 2! (или 5):
{{ myvar | pow(2) }}
{{ myvar | pow(5) }}
Квадратный корень или 5-й:
{{ myvar | root }}
{{ myvar | root(5) }}
Управление сетевыми взаимодействиями
Эти фильтры помогут вам с распространёнными сетевыми задачами.
Примечание
Эти фильтры переместились в коллекцию ansible.netcommon. Следуйте инструкциям по установке, чтобы установить эту коллекцию.
Фильтры IP-адресов
Новое в версии 1.9.
Проверить, является ли строка допустимым IP-адресом:
{{ myvar | ansible.netcommon.ipaddr }}
Вы также можете потребовать определённой версии протокола IP:
{{ myvar | ansible.netcommon.ipv4 }}
{{ myvar | ansible.netcommon.ipv6 }}
Фильтр IP-адресов также может использоваться для извлечения определённой информации из IP-адреса. Например, чтобы получить сам IP-адрес из CIDR, можно использовать:
{{ '192.0.2.1/24' | ansible.netcommon.ipaddr('address') }}
Дополнительную информацию о фильтре ipaddr и полное руководство по использованию можно найти в фильтре ipaddr.
Фильтры сетевых команд CLI
Новое в версии 2.4.
Для преобразования вывода команды CLI сетевого устройства в структурированный вывод JSON используйте фильтр parse_cli:
{{ output | ansible.netcommon.parse_cli('path/to/spec') }}
Фильтр parse_cli загрузит файл спецификаций и пропустит вывод команды через него, возвращая вывод в формате JSON. Файл спецификаций YAML определяет, как анализировать вывод CLI.
Файл спецификаций должен иметь правильный формат YAML. Он определяет, как анализировать вывод CLI и возвращать данные JSON. Ниже приведен пример правильного файла спецификаций, который будет анализировать вывод команды show vlan.
---
vars:
vlan:
vlan_id: "{{ item.vlan_id }}"
name: "{{ item.name }}"
enabled: "{{ item.state != 'act/lshut' }}"
state: "{{ item.state }}"
keys:
vlans:
value: "{{ vlan }}"
items: "^(?P<vlan_id>\\d+)\\s+(?P<name>\\w+)\\s+(?P<state>active|act/lshut|suspended)"
state_static:
value: present
Файл спецификаций выше вернёт структуру данных JSON, которая является списком хэшей с проанализированной информацией о VLAN.
Ту же команду можно проанализировать в хэш, используя директивы key и values. Вот пример, как проанализировать вывод в значение хэша, используя ту же команду show vlan.
---
vars:
vlan:
key: "{{ item.vlan_id }}"
values:
vlan_id: "{{ item.vlan_id }}"
name: "{{ item.name }}"
enabled: "{{ item.state != 'act/lshut' }}"
state: "{{ item.state }}"
keys:
vlans:
value: "{{ vlan }}"
items: "^(?P<vlan_id>\\d+)\\s+(?P<name>\\w+)\\s+(?P<state>active|act/lshut|suspended)"
state_static:
value: present
Другой распространённый случай использования для анализа команд CLI — разбить большую команду на блоки, которые можно проанализировать. Это можно сделать, используя директивы start_block и end_block для разбиения команды на блоки, которые можно проанализировать.
---
vars:
interface:
name: "{{ item[0].match[0] }}"
state: "{{ item[1].state }}"
mode: "{{ item[2].match[0] }}"
keys:
interfaces:
value: "{{ interface }}"
start_block: "^Ethernet.*$"
end_block: "^$"
items:
- "^(?P<name>Ethernet\\d\\/\\d*)"
- "admin state is (?P<state>.+),"
- "Port mode is (.+)"
Приведённый выше пример проанализирует вывод команды show interface в список хэшей.
Сетевые фильтры также поддерживают анализ вывода команды CLI с помощью библиотеки TextFSM. Для анализа вывода CLI с TextFSM используйте следующий фильтр:
{{ output.stdout[0] | ansible.netcommon.parse_cli_textfsm('path/to/fsm') }}
Для использования фильтра TextFSM требуется установка библиотеки TextFSM.
Фильтры сетевых XML
Новое в версии 2.5.
Для преобразования XML-вывода команды сетевого устройства в структурированный вывод JSON используйте фильтр parse_xml:
{{ output | ansible.netcommon.parse_xml('path/to/spec') }}
Фильтр parse_xml загрузит файл спецификаций и пропустит вывод команды, отформатированный как JSON.
Файл спецификаций должен иметь правильный формат YAML. Он определяет, как анализировать вывод XML и возвращать данные JSON.
Ниже приведён пример правильного файла спецификаций, который будет анализировать вывод команды show vlan | display xml.
---
vars:
vlan:
vlan_id: "{{ item.vlan_id }}"
name: "{{ item.name }}"
desc: "{{ item.desc }}"
enabled: "{{ item.state.get('inactive') != 'inactive' }}"
state: "{% if item.state.get('inactive') == 'inactive'%} inactive {% else %} active {% endif %}"
keys:
vlans:
value: "{{ vlan }}"
top: configuration/vlans/vlan
items:
vlan_id: vlan-id
name: name
desc: description
state: ".[@inactive='inactive']"
Файл спецификаций выше вернёт структуру данных JSON, которая является списком хэшей с проанализированной информацией о VLAN.
Один и тот же командный запрос можно было бы распарсить в хэш, используя директивы ключа и значений. Вот пример того, как распарсить выходные данные в значение хэша, используя тот же командный запрос show vlan | display xml.
---
vars:
vlan:
key: "{{ item.vlan_id }}"
values:
vlan_id: "{{ item.vlan_id }}"
name: "{{ item.name }}"
desc: "{{ item.desc }}"
enabled: "{{ item.state.get('inactive') != 'inactive' }}"
state: "{% if item.state.get('inactive') == 'inactive'%} inactive {% else %} active {% endif %}"
keys:
vlans:
value: "{{ vlan }}"
top: configuration/vlans/vlan
items:
vlan_id: vlan-id
name: name
desc: description
state: ".[@inactive='inactive']"
Значение top — это XPath, относящийся к корневому узлу XML. В примере XML-выхода ниже, значение top равно configuration/vlans/vlan, что является выражением XPath, относящимся к корневому узлу (<rpc-reply>). configuration в значении top — это самый внешний контейнерный узел, а vlan — самый внутренний контейнерный узел.
items — это словарь пар ключ-значение, которые сопоставляют определённые пользователем имена выражениям XPath, выбирающим элементы. Выражение Xpath относительно значения XPath, содержащегося в top. Например, vlan_id в файле спецификации — это имя, определённое пользователем, а его значение vlan-id относительно значения XPath в top
Атрибуты XML-тегов можно извлечь с помощью выражений XPath. Значение state в спецификации — это выражение XPath, используемое для получения атрибутов тега vlan в выходном XML.
<rpc-reply>
<configuration>
<vlans>
<vlan inactive="inactive">
<name>vlan-1</name>
<vlan-id>200</vlan-id>
<description>This is vlan-1</description>
</vlan>
</vlans>
</configuration>
</rpc-reply>
Примечание
Дополнительную информацию об поддерживаемых выражениях XPath см. в XPath Support.
Фильтры VLAN сети
Введено в версии 2.8.
Используйте фильтр vlan_parser для преобразования неупорядоченного списка целых чисел VLAN в отсортированный строковый список целых чисел в соответствии с правилами списков VLAN, подобных IOS. Этот список имеет следующие свойства:
- VLANы перечислены в порядке возрастания.
- Три и более последовательных VLAN перечисляются с дефисом.
- Первая строка списка может иметь длину first_line_len символов.
- Последующие строки списка могут иметь длину other_line_len символов.
Чтобы отсортировать список VLAN:
{{ [3003, 3004, 3005, 100, 1688, 3002, 3999] | ansible.netcommon.vlan_parser }}
Этот пример отображает следующий отсортированный список:
['100,1688,3002-3005,3999']
Ещё один пример шаблона Jinja:
{% set parsed_vlans = vlans | ansible.netcommon.vlan_parser %}
switchport trunk allowed vlan {{ parsed_vlans[0] }}
{% for i in range (1, parsed_vlans | count) %}
switchport trunk allowed vlan add {{ parsed_vlans[i] }}
{% endfor %}
Это позволяет динамически генерировать списки VLAN на интерфейсе Cisco IOS с тегами. Вы можете сохранить исчерпывающий исходный список точных VLAN, необходимых для интерфейса, а затем сравнить его с результатами парсинга выходных данных IOS, которые фактически будут сгенерированы для конфигурации.
Шифрование и контроль целостности строк и паролей
Введено в версии 1.9.
Чтобы получить хэш sha1 строки:
{{ 'test1' | hash('sha1') }}
Чтобы получить хэш md5 строки:
{{ 'test1' | hash('md5') }}
Получить контроль целостности строки:
{{ 'test2' | checksum }}
Другие хэши (зависит от платформы):
{{ 'test2' | hash('blowfish') }}
Чтобы получить хэш пароля sha512 (случайная соль):
{{ 'passwordsaresecret' | password_hash('sha512') }}
Чтобы получить хэш пароля sha256 со специфической солью:
{{ 'secretpassword' | password_hash('sha256', 'mysecretsalt') }}
Идемпотентный метод генерации уникальных хэшей для каждой системы — использование соли, которая является согласованной между запусками:
{{ 'secretpassword' | password_hash('sha512', 65534 | random(seed=inventory_hostname) | string) }}
Доступные типы хэшей зависят от системы управления, выполняющей Ansible, ‘hash’ зависит от hashlib, password_hash зависит от passlib (https://passlib.readthedocs.io/en/stable/lib/passlib.hash.html).
Введено в версии 2.7.
Некоторые типы хэшей позволяют указывать параметр rounds:
{{ 'secretpassword' | password_hash('sha256', 'mysecretsalt', rounds=10000) }}
Обработка текста
Несколько фильтров работают с текстом, включая URL-адреса, имена файлов и имена путей.
Добавление комментариев в файлы
Фильтр comment позволяет создавать комментарии в файле из текста в шаблоне, с различными стилями комментариев. По умолчанию Ansible использует # для начала строки комментария и добавляет пустую строку комментария выше и ниже вашего текстового комментария. Например, следующее:
{{ "Plain style (default)" | comment }}
производит такой вывод:
# # Plain style (default) #
Ansible предлагает стили комментариев для C (//...), блока C (/*...*/), Erlang (%...) и XML (<!--...-->):
{{ "C style" | comment('c') }}
{{ "C block style" | comment('cblock') }}
{{ "Erlang style" | comment('erlang') }}
{{ "XML style" | comment('xml') }}
Вы можете определить пользовательский символ комментария. Этот фильтр:
{{ "My Special Case" | comment(decoration="! ") }}
производит:
! ! My Special Case !
Вы можете полностью настроить стиль комментария:
{{ "Custom style" | comment('plain', prefix='#######\n#', postfix='#\n#######\n ###\n #') }}
Это создаёт следующий вывод:
#######
#
# Custom style
#
#######
###
#
Фильтр также может применяться к любой переменной Ansible. Например, чтобы сделать вывод переменной ansible_managed более читаемым, мы можем изменить определение в файле ansible.cfg следующим образом:
[defaults]
ansible_managed = This file is managed by Ansible.%n
template: {file}
date: %Y-%m-%d %H:%M:%S
user: {uid}
host: {host}
а затем использовать переменную с фильтром comment:
{{ ansible_managed | comment }}
что производит такой вывод:
# # This file is managed by Ansible. # # template: /home/ansible/env/dev/ansible_managed/roles/role1/templates/test.j2 # date: 2015-09-10 11:02:58 # user: ansible # host: myhost #
Разделение URL-адресов
Введено в версии 2.4.
Фильтр urlsplit извлекает фрагмент, имя хоста, netloc, пароль, путь, порт, запрос, схему и имя пользователя из URL-адреса. Без аргументов возвращает словарь всех полей:
{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('hostname') }}
# => 'www.acme.com'
{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('netloc') }}
# => 'user:password@www.acme.com:9000'
{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('username') }}
# => 'user'
{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('password') }}
# => 'password'
{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('path') }}
# => '/dir/index.html'
{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('port') }}
# => '9000'
{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('scheme') }}
# => 'http'
{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('query') }}
# => 'query=term'
{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('fragment') }}
# => 'fragment'
{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit }}
# =>
# {
# "fragment": "fragment",
# "hostname": "www.acme.com",
# "netloc": "user:password@www.acme.com:9000",
# "password": "password",
# "path": "/dir/index.html",
# "port": 9000,
# "query": "query=term",
# "scheme": "http",
# "username": "user"
# }
Поиск строк с помощью регулярных выражений
Чтобы найти строку с помощью регулярного выражения, используйте фильтр «regex_search»:
# search for "foo" in "foobar"
{{ 'foobar' | regex_search('(foo)') }}
# will return empty if it cannot find a match
{{ 'ansible' | regex_search('(foobar)') }}
# case insensitive search in multiline mode
{{ 'foo\nBAR' | regex_search("^bar", multiline=True, ignorecase=True) }}
Чтобы найти все вхождения совпадений регулярного выражения, используйте фильтр «regex_findall»:
# Return a list of all IPv4 addresses in the string
{{ 'Some DNS servers are 8.8.8.8 and 8.8.4.4' | regex_findall('\\b(?:[0-9]{1,3}\\.){3}[0-9]{1,3}\\b') }}
Чтобы заменить текст в строке с помощью регулярного выражения, используйте фильтр «regex_replace»:
# convert "ansible" to "able"
{{ 'ansible' | regex_replace('^a.*i(.*)$', 'a\\1') }}
# convert "foobar" to "bar"
{{ 'foobar' | regex_replace('^f.*o(.*)$', '\\1') }}
# convert "localhost:80" to "localhost, 80" using named groups
{{ 'localhost:80' | regex_replace('^(?P<host>.+):(?P<port>\\d+)$', '\\g<host>, \\g<port>') }}
# convert "localhost:80" to "localhost"
{{ 'localhost:80' | regex_replace(':80') }}
# change a multiline string
{{ var | regex_replace('^', '#CommentThis#', multiline=True) }}
Примечание
Если вы хотите сопоставить всю строку, и вы используете *, убедитесь, что всегда обёртываете регулярное выражение якорями начала/конца. Например, ^(.*)$ всегда будет соответствовать только одному результату, в то время как (.*) на некоторых версиях Python будет соответствовать всей строке и пустой строке в конце, что означает, что это произведёт два замены:
# add "https://" prefix to each item in a list
GOOD:
{{ hosts | map('regex_replace', '^(.*)$', 'https://\\1') | list }}
{{ hosts | map('regex_replace', '(.+)', 'https://\\1') | list }}
{{ hosts | map('regex_replace', '^', 'https://') | list }}
BAD:
{{ hosts | map('regex_replace', '(.*)', 'https://\\1') | list }}
# append ':80' to each item in a list
GOOD:
{{ hosts | map('regex_replace', '^(.*)$', '\\1:80') | list }}
{{ hosts | map('regex_replace', '(.+)', '\\1:80') | list }}
{{ hosts | map('regex_replace', '$', ':80') | list }}
BAD:
{{ hosts | map('regex_replace', '(.*)', '\\1:80') | list }}
Примечание
До Ansible 2.0, если фильтр «regex_replace» использовался с переменными внутри YAML-аргументов (в отличие от более простых аргументов «ключ=значение»), тогда вам нужно было экранировать обратные ссылки (например, \\1) четырьмя обратными слешами (\\\\) вместо двух (\\).
Введено в версии 2.0.
Чтобы экранировать специальные символы в стандартном регулярном выражении Python, используйте фильтр «regex_escape» (используя параметр re_type=’python’ по умолчанию):
# convert '^f.*o(.*)$' to '\^f\.\*o\(\.\*\)\$'
{{ '^f.*o(.*)$' | regex_escape() }}
Введено в версии 2.8.
Чтобы экранировать специальные символы в регулярном выражении POSIX basic, используйте фильтр «regex_escape» с параметром re_type=’posix_basic’:
# convert '^f.*o(.*)$' to '\^f\.\*o(\.\*)\$'
{{ '^f.*o(.*)$' | regex_escape('posix_basic') }}
Управление именами файлов и именами путей
Чтобы получить последнее имя файла, как ‘foo.txt’ из ‘/etc/asdf/foo.txt’:
{{ path | basename }}
Чтобы получить последнее имя файла в стиле Windows (введено в версии 2.0):
{{ path | win_basename }}
Чтобы отделить букву диска Windows от остальной части пути к файлу (введено в версии 2.0):
{{ path | win_splitdrive }}
Чтобы получить только букву диска Windows:
{{ path | win_splitdrive | first }}
Чтобы получить остальную часть пути без буквы диска:
{{ path | win_splitdrive | last }}
Чтобы получить директорию из пути:
{{ path | dirname }}
Чтобы получить директорию из пути в стиле Windows (введена в версии 2.0):
{{ path | win_dirname }}
Чтобы расширить путь, содержащий символ тильды (~) (введено в версии 1.5):
{{ path | expanduser }}
Чтобы расширить путь, содержащий переменные окружения:
{{ path | expandvars }}
Примечание
expandvars расширяет локальные переменные; его использование для удалённых путей может привести к ошибкам.
Введено в версии 2.6.
Чтобы получить реальный путь ссылки (введено в версии 1.8):
{{ path | realpath }}
Чтобы получить относительный путь ссылки от начальной точки (введено в версии 1.7):
{{ path | relpath('/etc') }}
Чтобы получить корень и расширение пути или имени файла (введено в версии 2.0):
# with path == 'nginx.conf' the return would be ('nginx', '.conf')
{{ path | splitext }}
Фильтр splitext возвращает строку. К отдельным компонентам можно получить доступ, используя фильтры first и last:
# with path == 'nginx.conf' the return would be 'nginx'
{{ path | splitext | first }}
# with path == 'nginx.conf' the return would be 'conf'
{{ path | splitext | last }}
Чтобы объединить один или несколько компонентов пути:
{{ ('/etc', path, 'subdir', file) | path_join }}
Введено в версии 2.10.
Обработка строк
Чтобы добавить кавычки для использования в командной строке:
- name: Run a shell command
ansible.builtin.shell: echo {{ string_value | quote }}
Чтобы конкатенировать список в строку:
{{ list | join(" ") }}
Чтобы разделить строку на список:
.. versionadded:: 2.11
{{ csv_string | split(“,”) }}
Чтобы работать со строками, закодированными в Base64:
{{ encoded | b64decode }}
{{ decoded | string | b64encode }}
Начиная с версии 2.6, вы можете определить тип кодирования, по умолчанию используется utf-8:
{{ encoded | b64decode(encoding='utf-16-le') }}
{{ decoded | string | b64encode(encoding='utf-16-le') }}
Примечание
Фильтр string необходим только для Python 2 и гарантирует, что текст для кодирования — это строка Unicode. Без этого фильтра перед b64encode будет закодировано неправильное значение.
Введено в версии 2.6.
Управление UUID
Чтобы создать UUIDv5 с именем пространства:
{{ string | to_uuid(namespace='11111111-2222-3333-4444-555555555555') }}
Введено в версии 2.10.
Чтобы создать UUIDv5 с именем пространства, используя стандартное пространство Ansible ‘361E6D51-FAEC-444A-9079-341386DA8E2E’:
{{ string | to_uuid }}
Введено в версии 1.9.
Чтобы использовать один атрибут из каждого элемента в списке сложных переменных, используйте Jinja2 map filter:
# get a comma-separated list of the mount points (for example, "/,/mnt/stuff") on a host
{{ ansible_mounts | map(attribute='mount') | join(',') }}
Обработка дат и времени
Чтобы получить объект даты из строки, используйте фильтр to_datetime:
# Get total amount of seconds between two dates. Default date format is %Y-%m-%d %H:%M:%S but you can pass your own format
{{ (("2016-08-14 20:00:12" | to_datetime) - ("2015-12-25" | to_datetime('%Y-%m-%d'))).total_seconds() }}
# Get remaining seconds after delta has been calculated. NOTE: This does NOT convert years, days, hours, and so on to seconds. For that, use total_seconds()
{{ (("2016-08-14 20:00:12" | to_datetime) - ("2016-08-14 18:00:00" | to_datetime)).seconds }}
# This expression evaluates to "12" and not "132". Delta is 2 hours, 12 seconds
# get amount of days between two dates. This returns only number of days and discards remaining hours, minutes, and seconds
{{ (("2016-08-14 20:00:12" | to_datetime) - ("2015-12-25" | to_datetime('%Y-%m-%d'))).days }}
Примечание
Полный список кодов формата для работы со строками формата дат Python см. в https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior.
Новое в версии 2.4.
Для форматирования даты с помощью строки (как в команде shell date), используйте фильтр «strftime»:
# Display year-month-day
{{ '%Y-%m-%d' | strftime }}
# Display hour:min:sec
{{ '%H:%M:%S' | strftime }}
# Use ansible_date_time.epoch fact
{{ '%Y-%m-%d %H:%M:%S' | strftime(ansible_date_time.epoch) }}
# Use arbitrary epoch value
{{ '%Y-%m-%d' | strftime(0) }} # => 1970-01-01
{{ '%Y-%m-%d' | strftime(1441357287) }} # => 2015-09-04
Примечание
Чтобы получить все возможные строки, проверьте https://docs.python.org/3/library/time.html#time.strftime
Получение имён ресурсов Kubernetes
Примечание
Эти фильтры мигрировали в коллекцию community.kubernetes. Следуйте инструкциям по установке, чтобы установить эту коллекцию.
Используйте фильтр «k8s_config_resource_name», чтобы получить имя Kubernetes ConfigMap или Secret, включая его хэш:
{{ configmap_resource_definition | community.kubernetes.k8s_config_resource_name }}
Это можно использовать для ссылки на хэши в спецификациях Pod:
my_secret:
kind: Secret
name: my_secret_name
deployment_resource:
kind: Deployment
spec:
template:
spec:
containers:
- envFrom:
- secretRef:
name: {{ my_secret | community.kubernetes.k8s_config_resource_name }}
Новое в версии 2.8.
См. также
- Введение в плейбуки
-
Введение в плейбуки
- Условные операторы
-
Условные операторы в плейбуках
- Использование переменных
-
Всё о переменных
- Циклы
-
Циклы в плейбуках
- Роли
-
Организация плейбуков по ролям
- Советы и рекомендации
-
Советы и рекомендации для плейбуков
- Список рассылки пользователей
-
У вас есть вопрос? Задайте его в группе Google!
- irc.freenode.net
-
Канал IRC чата #ansible
© 2012–2018 Michael DeHaan
© 2018–2021 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.11/user_guide/playbooks_filters.html