Здесь показаны различия между двумя версиями данной страницы.
| Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
|
linux:ansible:filters [2023/12/30 16:23] werwolf |
linux:ansible:filters [2023/12/30 16:25] (текущий) werwolf |
||
|---|---|---|---|
| Строка 13: | Строка 13: | ||
| Попробуйте запустить у себя следующий плейбук, выводящий значения ''ansible_mounts'': | Попробуйте запустить у себя следующий плейбук, выводящий значения ''ansible_mounts'': | ||
| - | <code> | + | <code yaml> |
| --- | --- | ||
| - name: Test ansible_mounts | - name: Test ansible_mounts | ||
| Строка 27: | Строка 27: | ||
| В выводе получится что-то вроде такого: | В выводе получится что-то вроде такого: | ||
| - | <code> | + | <code bash> |
| TASK [Show ansible_mounts] ********************************************* | TASK [Show ansible_mounts] ********************************************* | ||
| ok: [localhost] => | ok: [localhost] => | ||
| Строка 78: | Строка 78: | ||
| Давайте попробуем отфильтровать из этого длинного списка только те значения, для которых значение ключа ''device'' содержит /dev/sda. Это можно сделать с помощью фильтра selectattr и [[https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_tests.html#testing-strings|теста match]]: | Давайте попробуем отфильтровать из этого длинного списка только те значения, для которых значение ключа ''device'' содержит /dev/sda. Это можно сделать с помощью фильтра selectattr и [[https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_tests.html#testing-strings|теста match]]: | ||
| - | <code> | + | <code yaml> |
| --- | --- | ||
| - name: Show ansible_mounts filtered | - name: Show ansible_mounts filtered | ||
| Строка 92: | Строка 92: | ||
| Получим примерно такое: | Получим примерно такое: | ||
| - | <code> | + | <code bash> |
| TASK [Show ansible_mounts] ********************************* | TASK [Show ansible_mounts] ********************************* | ||
| ok: [localhost] => | ok: [localhost] => | ||
| Строка 142: | Строка 142: | ||
| Теперь давайте предположим, что нам из всего набора ключей каждого словаря нужно только значение ключа ''mount''. Как выбрать из полученного списка лишь значения определенного ключа? Тут нам на помощь придет фильтр map. Это довольно мощный фильтр, суть которого сводится к тому, что он применяет фильтр с аргументами, которые сами переданы ему в качестве аргументов, к каждому элементу списка словарей, которые приходят на вход. В простейшем случае, если нам нужно просто получить значение конкретного ключа из каждого элемента списка словарей, использование данного фильтра будет очень простым. Нужно просто указать значение нужного имени ключа в виде атрибута фильтра с соответствующей командой. В нашем случае это будет ''map(attribute='mount')''. В результате получим следующий код: | Теперь давайте предположим, что нам из всего набора ключей каждого словаря нужно только значение ключа ''mount''. Как выбрать из полученного списка лишь значения определенного ключа? Тут нам на помощь придет фильтр map. Это довольно мощный фильтр, суть которого сводится к тому, что он применяет фильтр с аргументами, которые сами переданы ему в качестве аргументов, к каждому элементу списка словарей, которые приходят на вход. В простейшем случае, если нам нужно просто получить значение конкретного ключа из каждого элемента списка словарей, использование данного фильтра будет очень простым. Нужно просто указать значение нужного имени ключа в виде атрибута фильтра с соответствующей командой. В нашем случае это будет ''map(attribute='mount')''. В результате получим следующий код: | ||
| - | <code> | + | <code yaml> |
| --- | --- | ||
| - name: Show ansible_mounts filtered | - name: Show ansible_mounts filtered | ||
| Строка 173: | Строка 173: | ||
| Как видим, получить нужный нам набор данных оказывается весьма просто даже без использования программирования и циклов. Давайте усложним задачу. Скажем, нам нужно получить в выводе значения не только ключа mount, но также значения ключей ''size_available'' и ''size_total''. Идущие в комплекте фильтры так не умеют. Фильтры Ansible умеют фильтровать списки и списки словарей, но не сами ключи словаря. Выход прост: нужно превратить словарь в список и уже его отфильтровать имеющимися инструментами. К счастью, в Ansible есть подходящие фильтры для такой задачи. С их помощью можно превращать словари в списки, а списки — обратно в словари. Называются эти фильтры, соответственно, [[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/dict2items_filter.html|dict2items]] и [[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/items2dict_filter.html|items2dict]]. | Как видим, получить нужный нам набор данных оказывается весьма просто даже без использования программирования и циклов. Давайте усложним задачу. Скажем, нам нужно получить в выводе значения не только ключа mount, но также значения ключей ''size_available'' и ''size_total''. Идущие в комплекте фильтры так не умеют. Фильтры Ansible умеют фильтровать списки и списки словарей, но не сами ключи словаря. Выход прост: нужно превратить словарь в список и уже его отфильтровать имеющимися инструментами. К счастью, в Ansible есть подходящие фильтры для такой задачи. С их помощью можно превращать словари в списки, а списки — обратно в словари. Называются эти фильтры, соответственно, [[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/dict2items_filter.html|dict2items]] и [[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/items2dict_filter.html|items2dict]]. | ||
| - | Например, у нас есть следующий словарь: | + | Например, у нас есть следующий словарь: |
| - | <code> | + | <code yaml> |
| server_config: | server_config: | ||
| apache: | apache: | ||
| Строка 193: | Строка 193: | ||
| И мы хотим отфильтровать только те элементы словаря, где есть ключ ''version''. Сделать это мы сможем так. Сначала превращаем словать в список с помощью фильтра dict2items: | И мы хотим отфильтровать только те элементы словаря, где есть ключ ''version''. Сделать это мы сможем так. Сначала превращаем словать в список с помощью фильтра dict2items: | ||
| - | <code> | + | <code yaml> |
| server_config | dict2items | server_config | dict2items | ||
| </code> | </code> | ||
| Строка 199: | Строка 199: | ||
| Получим: | Получим: | ||
| - | <code> | + | <code bash> |
| ok: [localhost] => | ok: [localhost] => | ||
| server_config | dict2items: | server_config | dict2items: | ||
| Строка 230: | Строка 230: | ||
| Теперь отфильтруем только те элементы списка, которые содержат дочерний ключ ''version'': | Теперь отфильтруем только те элементы списка, которые содержат дочерний ключ ''version'': | ||
| - | <code> | + | <code yaml> |
| server_config | dict2items | selectattr('value.version', 'defined') | server_config | dict2items | selectattr('value.version', 'defined') | ||
| </code> | </code> | ||
| Строка 236: | Строка 236: | ||
| Получим: | Получим: | ||
| - | <code> | + | <code bash> |
| ok: [localhost] => | ok: [localhost] => | ||
| server_config | dict2items | selectattr('value.version', 'defined'): | server_config | dict2items | selectattr('value.version', 'defined'): | ||
| Строка 263: | Строка 263: | ||
| Теперь превратим обратно список в словарь исходного вида. Для этого добавим в конец конвейера фильтр ''items2dict''. Получаем: | Теперь превратим обратно список в словарь исходного вида. Для этого добавим в конец конвейера фильтр ''items2dict''. Получаем: | ||
| - | <code> | + | <code bash> |
| ok: [localhost] => | ok: [localhost] => | ||
| server_config | dict2items | selectattr('value.version', 'defined') | items2dict: | server_config | dict2items | selectattr('value.version', 'defined') | items2dict: | ||
| Строка 287: | Строка 287: | ||
| Теперь давайте вспомним про нашу исходную задачу со списком словарей ''ansible_mounts'' из которого мы хотим извлечь только некоторые ключи. Сам список мы уже отфильтровали по нужному нам условию, теперь нам нужно выбрать только определенные ключи из списка. Получается, что к каждому элементу списка словарей нужно применить фильтр ''dict2items'', потом отфильтровать этот список по списку ключей, а потом обратно превратить каждый дочерний список обратно в словарь. Сложно? На самом деле не очень. Как работать со словарем, мы уже видели на примере выше. Теперь нам нужно проделать то же самое со списком словарей. Тут нам как раз поможет упоминавшийся выше фильтр ''map'', только уже в более продвинутом варианте применения. Покажем сразу итоговый результат. Код: | Теперь давайте вспомним про нашу исходную задачу со списком словарей ''ansible_mounts'' из которого мы хотим извлечь только некоторые ключи. Сам список мы уже отфильтровали по нужному нам условию, теперь нам нужно выбрать только определенные ключи из списка. Получается, что к каждому элементу списка словарей нужно применить фильтр ''dict2items'', потом отфильтровать этот список по списку ключей, а потом обратно превратить каждый дочерний список обратно в словарь. Сложно? На самом деле не очень. Как работать со словарем, мы уже видели на примере выше. Теперь нам нужно проделать то же самое со списком словарей. Тут нам как раз поможет упоминавшийся выше фильтр ''map'', только уже в более продвинутом варианте применения. Покажем сразу итоговый результат. Код: | ||
| - | <code> | + | <code yaml> |
| - name: Show mounts data | - name: Show mounts data | ||
| debug: | debug: | ||
| Строка 300: | Строка 300: | ||
| И результат: | И результат: | ||
| - | <code> | + | <code bash> |
| ok: [localhost] => | ok: [localhost] => | ||
| ? |- | ? |- | ||
| Строка 334: | Строка 334: | ||
| * Наконец, после фильтрации нужных ключей, каждый список пар ключ-значение преобразуется обратно в словарь с помощью ''map'' и фильтра ''items2dict''. | * Наконец, после фильтрации нужных ключей, каждый список пар ключ-значение преобразуется обратно в словарь с помощью ''map'' и фильтра ''items2dict''. | ||
| - | ===== Заключение ===== | ||
| - | |||
| - | Мы познакомились с наглядными примерами использования фильтров Ansible, и, надеюсь, теперь они кажутся вам не такими уж сложными. Ведь часто всё кажется сложным, пока не попробуешь. С фильтрами Ansible точно так же: попробуйте, поэкспериментируйте, и вы увидите, как они могут упростить вашу жизнь. А еще напишите в комментариях, хотели бы вы увидеть продолжение статьи с другими интересными примерами фильтров? Если тема будет интересна, то в следующих статьях попробую в том числе раскрыть тему написания своих собственных кастомных фильтров. | ||
| - | |||
| - | |||
| - | |||
| - | Теги: | ||
| - | |||
| - | * [[:ru:search:?target_type=posts&order=relevance&q=%5Bansible%5D|ansible]] | ||
| - | * [[:ru:search:?target_type=posts&order=relevance&q=%5B%D1%84%D0%B8%D0%BB%D1%8C%D1%82%D1%80%D1%8B%5D|фильтры]] | ||
| - | * [[:ru:search:?target_type=posts&order=relevance&q=%5Bmap%5D|map]] | ||
| - | * [[:ru:search:?target_type=posts&order=relevance&q=%5Bselectattr%5D|selectattr]] | ||
| - | * [[:ru:search:?target_type=posts&order=relevance&q=%5Bitems2dict%5D|items2dict]] | ||
| - | * [[:ru:search:?target_type=posts&order=relevance&q=%5Bdict2items%5D|dict2items]] | ||
| - | * [[:ru:search:?target_type=posts&order=relevance&q=%5Bjinja2%5D|jinja2]] | ||
| - | |||
| - | Хабы: | ||
| - | * [[:ru:hubs:sys_admin:|Системное администрирование]] | ||
| - | * [[:ru:hubs:it-infrastructure:|IT-инфраструктура]] | ||
| - | * [[:ru:hubs:s_admin:|Серверное администрирование]] | ||
| - | * [[:ru:hubs:devops:|DevOps]] | ||