Ansible вывести сообщение на экран
Обновлено: 30.06.2024
Иногда требуется выполнить задачу на определённом узле, но в контексте другого узла. Например, во время обновления узла может возникнуть необходимость отключить для него мониторинг, находящийся на отдельном сервере. Для этого используется управляющая директива delegate_to. Приведём пример:
- name : disable nagios alerts span class= "hljs-keyword" > for /span > span class= "hljs-keyword" > this /span > host webserver service
Результатом выполнения этой задачи будет отключение сообщений для сервиса dnsserver в Nagios.
Выражение ‘When’ в Ansible: Проверка Переменных
Узнать определена ли (существует ли) переменная в Ansible:
Проверить является ли переменная в Ansible пустой:
Убедиться что переменная в Ansible определена и не является пустой:
Узнать имеет ли переменная в Ansible значение True или False:
выполнение задачи на определённой группе из группы:
cat /etc/ansible/hosts
[nfs:children]
nfsmaster
nfsclient
[nfsmaster]
192.168.1.112
[nfsclient]
192.168.1.111
192.168.1.110
Во время отладки плейбука в Ansible, полезно знать как, отобразить заданные переменные или известные о хосте факты.
В Ansible, для печати сообщений из плейбука, а также для вывода значений переменных, мы можем использовать модуль debug .
В следующих примерах я показываю, как напечатать конкретные переменные в Ansible и как вывести список всех известных фактов и переменных в Ansible с помощью плейбука.
Debug Ansible Playbook — Печать Переменных
Вывести значение переменной:
Напечатать переменную только если она определена:
Печать нескольких переменных:
Вывести список всех известных фактов и переменных:
В Jinja2-темплейтах является хорошей практикой заранее проверять существует ли переменная и какое у нее значение.
Существует несколько полезных проверок, которые вы можете сделать с помощью встроенных в Jinja2 тестов и фильтров.
В этой статье я покажу, как проверить, существует ли переменная, является ли она пустой или она установлена в значение True.
Проверка Переменной в Jinja2
Проверить существует ли (определена ли) переменная:
Проверить является ли пустой переменная:
Проверить установлена ли в значение true переменная:
Проверить что переменная существует и не является пустой:
Проверить что переменная существует и установлена в значение true:
Ещё немного о WHEN
Использование когда с фактами
Вы можете использовать условные выражения when для запуска задачи, только если выполняется определенное условие. Для демонстрации создайте новую книгу воспроизведения с именем ubuntu-server.yml со следующим содержимым:
Теперь запустите playbook:
Обратите внимание, как мы использовали факт Ansible ansible_facts[‘distribution’] в условии when, чтобы проверить, на каких узлах работает Ubuntu. Также обратите внимание, что вам не нужно заключать переменные в фигурные скобки при использовании условных выражений when.
В выходных данных playbook обратите внимание, как TASK [Detect Ubuntu Servers] пропущены первые три узла, поскольку все они работают под CentOS и работают только на node4, поскольку он работает под управлением Ubuntu.
В этом разделе рассматриваются несколько способов, которые позволяют посмотреть на вывод, полученный с устройств.
Примеры используют модуль raw, но аналогичные принципы работают и с другими модулями.
verbose¶
В предыдущих разделах один из способов отобразить результат выполнения команд уже использовался - флаг verbose.
Конечно, вывод не очень удобно читать, но, как минимум, он позволяет увидеть, что команды выполнились. Также этот флаг позволяет подробно посмотреть, какие шаги выполняет Ansible.
Пример запуска playbook с флагом verbose (вывод сокращен):
При увеличении количества букв v в флаге, вывод становится более подробным. Попробуйте вызывать этот же playbook и добавлять к флагу буквы v (5 и больше показывают одинаковый вывод) таким образом:
В выводе видны результаты выполнения задачи, они возвращаются в формате JSON:
- changed - ключ, который указывает, были ли внесены изменения
- stdout - вывод команды
- stdout_lines - вывод в виде списка команд, разбитых построчно
register¶
Параметр register сохраняет результат выполнения модуля в переменную. Затем эта переменная может использоваться в шаблонах, в принятии решений о ходе сценария или для отображения вывода.
Попробуем сохранить результат выполнения команды.
В playbook 2_register_vars.yml с помощью register вывод команды sh ip int br сохранен в переменную sh_ip_int_br_result:
Если запустить этот playbook, вывод не будет отличаться, так как вывод только записан в переменную, но с переменной не выполняется никаких действий. Следующий шаг - отобразить результат выполнения команды с помощью модуля debug.
debug¶
Модуль debug позволяет отображать информацию на стандартный поток вывода. Это может быть произвольная строка, переменная, факты об устройстве.
Для отображения сохраненных результатов выполнения команды, в playbook 2_register_vars.yml добавлена задача с модулем debug:
Обратите внимание, что выводится не всё содержимое переменной sh_ip_int_br_result, а только содержимое stdout_lines. В sh_ip_int_br_result.stdout_lines находится список строк, поэтому вывод будет структурирован.
Результат запуска playbook выглядит так:
register, debug, when¶
С помощью ключевого слова when можно указать условие, при выполнении которого задача выполняется. Если условие не выполняется, то задача пропускается.
when в Ansible используется, как if в Python.
Пример playbook 3_register_debug_when.yml:
В последнем задании несколько изменений:
Выполнение того же playbook, но после удаления адреса на устройстве:
© Copyright 2020, Natasha Samoylenko Revision 6764fe74 .
Versions latest Downloads pdf html epub On Read the Docs Project Home Builds Free document hosting provided by Read the Docs.
Oct 26, 2015 18:53 · 541 words · 3 minute read ansible
В предыдущей статье мы успешно установили и проверили работоспособность системы управления конфигурациями Ansible , а так же написали и выполнили первый набор инструкций (playbook). Давайте разберемся с результатами его выполнения!
GATHERING FACTS — это первая задача, которая по умолчанию присутствует в любом наборе инструкций. Как видим из названия задачи, ее цель — сбор метаданных об удаленных хостах в форме переменных (например ip-адреса, имени хоста, установленной ОС). Полученные данные могут быть использованы в следующих задачах, описанных в playbook.
Посмотреть переменные и их значения можно командой:
Дальше в выводе следуют задачи, описанные в секции task: набора инструкций и результаты их выполнения:
- TASK: [Install package nginx] — установка web-сервера nginx ;
- TASK: [Starting service nginx] — запуск web-сервера nginx .
Первая задача выполнена с изменениями, о чем свидетельствует состояние changed — все верно, раньше web-сервера nginx в системе не было, теперь он установлен.
Вторая задача выполнена без изменений, так как web-сервер nginx автоматически запускается после установки.
Для сравнения результатов вывода, запустим данный набор инструкций еще раз:
Видим, что результаты выполнения задачи Install package nginx отличаются от предыдущего запуска playbook.
Последняя секция в выводе результатов выполнения набора инструкций — PLAY RECAP . Здесь присутствуют четыре параметра:
- ok — количество выполняемых задач (включая задачу GATHERING FACTS );
- changed — количество измененных состояний на удаленном хосте;
- unreachable — количество хостов, которые были недоступны по время выполнения набора инструкций;
- failed — количество невыполненных задач на удаленном хосте. Подробности выполнения набора инструкций (playbook) можно увидеть с помощью вывода отладочной информации одного из трех доступных уровней ( -v , -vv и -vvv соответственно).
Также для отладки часто выводят переменные, полученные с удаленных хостов при выполнении задачи GATHERING FACTS , для этого достаточно в playbook добавить такую задачу:
Результатом выполнения такого набора инструкций будет:
Запустить только конкретную задачу из playbook можно командой:
Весьма полезной является возможность вызывать набор инструкций из другого набора инструкций. Хороший пример — обновление установленных пакетов в ОС. Для этого создадим playbook update_os.yml со следующим содержанием:
Этот playbook можно включить как задачу в набор инструкций install_nginx.yml , который мы создавали в предыдущей статье:
И теперь, перед установкой web-сервера nginx на удаленных хостах будут обновлены установленные пакеты.
В следующей статье рассмотрим использование условий и переменных в наборах инструкций.
Говоря о типовых сценариях автоматизации сети, никак не обойтись без набора модулей command. Благодаря этим модулям, Ansible позволяет запускать команды на сетевом оборудовании так, как будто вы вводите их прямо с консоли. При этом вывод команд не просто проскакивает в окне терминала, чтобы кануть в лету, а может быть сохранен и использован в дальнейшем. Его можно записать в переменные, парсить для использования в последующих задачах или же сохранить на будущее в переменных хоста.
Цель этого поста – показать, что любую повторяющуюся задачу по управлению сетью можно автоматизировать, и что Ansible не просто позволяет управлять конфигурациями, а помогает избавиться от рутины и сэкономить время.
Разберем базовые способы использования сетевых модулей command, включая сохранение вывода команд с помощью параметра register. Также рассмотрим, как выполнять масштабирование на несколько сетевых устройств с помощью hostvars и как организовать условное выполнение с помощью параметра wait_for и еще трех связанных параметров: interval, retries и match.
Для различных сетевых платформ есть свои модули command, причем все они поддерживаются на уровне расширения Red Hat Ansible Engine Networking Add-on:
Сетевые платформы | Модули *os_command |
Arista EOS | eos_command |
Cisco IOS / IOS-XE | ios_command |
Cisco IOS-XR | iosxr_command |
Cisco NX-OS | nxos_command |
Juniper Junos | junos_command |
VyOS | vyos_command |
Основы работы с модулями command
Рассмотрим плейбук, который просто запускает команду show version с помощью модуля eos_command:
Здесь у нас две задачи и первая использует модуль eos_command с единственным параметром commands. Поскольку мы запускаем только одну команду – show version – ее можно указать в той же строке, что и сам параметр commands. Если команд две и больше, то каждую их них надо размещать на отдельной строке после commands:. В этом примере мы используем ключевое слово register, чтобы сохранить вывод команды show version. Параметр register (его можно использовать в любой задаче Ansible) задает переменную, куда будет сохранен вывод нашей задачи, чтобы им можно было воспользоваться позже. В нашем примере эта переменная называется output.
Вторая задача в нашем примере использует модуль debug, чтобы вывести на экран содержимое только что созданной переменой output. То есть, это те же данные, что вы увидели бы в интерфейсе командной строки на устройстве EOS, если бы ввели там “show version”. Отличие в том, что наш плейбук покажет их в окне терминала, на котором вы его запускаете. Как видите, модуль debug позволяет легко проверить переменные Ansible.
Вот как выглядит вывод нашего плейбука:
Сравним вывод команды на устройстве и в Ansible:
Две открывающие скобки указывают на то, что stdout_lines на самом деле возвращает перечень списков строк. Если слегка изменить нашу debug-задачу, то эту фишку можно использовать для выборочного просмотра результатов выполнения команды. Поскольку в нашем перечне есть только один список строк, этот список называется нулевым (вообще-то он первый, но отсчет идет с нуля). Теперь посмотрим, как извлечь из него отдельную строку, допустим, System MAC Address. В выводе команды эта строка идет четвертой по счету, но поскольку считаем с нуля, нам, в итоге, нужна строка 3 из списка 0, иначе говоря: output.stdout_lines[0][3].
Какой смысл в нумерации списков и зачем она вообще нужна? Дело в том, что в рамках одной задачи можно запускать несколько команд, например, вот так (здесь у нас три команды):
Вот как выглядит вывод:
Здесь список номер ноль – это вывод команды show version, список номер один – вывод show ip int br, список номер два – вывод show int status. То есть номер списка определяется порядком выполнения команд.
Команды Arista EOS | Соответствующие списки вывода |
show version | output.stdout_lines[0] |
show ip int br | output.stdout_lines[1] |
show int status | output.stdout_lines[2] |
Масштабирование модуля command: переменные хоста
А что будет, если запустить плейбук на нескольких устройствах одновременно?
Чтобы сохранить однозначность, переменная output сохраняется как переменная хоста для каждого хоста в inventory. Если у нас есть три коммутатора, и мы прогоним на них наш плейбук, то получим переменную output для каждого уникального хоста. Допустим, нам нужен IP-адрес из команды show ip int br для порта Ethernet1 на коммутаторе switch03. Поскольку show ip int br – это вторая по счету команда, которая запускается в рамках задачи, а данные по интерфейсу Ethernet1 содержатся во второй строке ее вывода, то нам надо будет написать stdout_lines[1][1]. Чтобы обращаться к переменным конкретного хоста, мы используем ключевое слово hostvars и выполняем поиск нужного нам хоста по имени.
Вот как это делается:
В результате output содержит именно то, что нам нужно:
По умолчанию задача использует переменные текущего хоста, но hostvars позволяет напрямую обратиться и к переменным другого хоста.
Условия в задачах с модулями command: параметр wait_for
Параметр wait_for позволяет реализовать проверку условий сразу после выполнения команды. Например, сделать так, что задача будет считаться выполненной успешно, только если вывод команды проверки статуса содержит определенный текст. По умолчанию параметр wait_for не используется, поэтому задача запускается только один раз, как в примерах выше. Но если задать его в явном виде, задача будет повторно запускаться до тех пор, пока не выполнится условие либо не кончится лимит попыток (по умолчанию их 10). Если включить журналирование команд, то можно увидеть, что в приведенном ниже плейбуке (который специально написан так, чтобы условие никогда не выполнилось) все происходит именно так.
Этот плейбук будет 10 раз запускать команду show int status, поскольку в ее выводе никогда не будет строки DURHAM.
В этом можно убедиться с помощью команды show logging:
Теперь рассмотрим пример реального плейбука, в котором все настроено для установления OSPF-соседства (adjacency) с другим устройством, кроме команды ip ospf area. Мы применим эту команду и затем воспользуемся параметром wait_for, чтобы проверить наличие в выводе слова FULL: если оно там есть, то соседство успешно установлено. Если за 10 попыток FULL так и не появится, то задача завершится с ошибкой.
Выполним этот плейбук с помощью команды ansible-playbook:
Смотрим командную строку и видим, что плейбук выполнен успешно:
Помимо contains можно использовать следующие операторы сравнения:
- eq: – равно
- neq: – не равно
- gt: – больше
- ge: – больше или равно
- lt: – меньше
- le: – меньше или равно
Параметр | Описание |
interval | Время между повторами команды. |
retries | Макс. количество повторов, прежде чем задача завершится с ошибкой, либо будет выполнено условие. |
match | Совпадение всех условия или хотя бы одного. |
Остановимся чуть подробнее на параметре match:
Когда задано match: any, задача считается успешной, если результат содержит FULL или 172.16.1.2. Если же задано match: all, то результат должен содержать и FULL, и 172.16.1.2. По умолчанию используется match: all, поскольку если вы прописываете несколько условий, то, скорее всего, хотите, чтобы они выполнялись все, а не хотя бы одно.
Когда может пригодиться match: any? Допустим, надо проверить, что дата-центр имеет двустороннюю связь с интернетом. А дата-центр подключен к пяти разным интернет-провайдерам, для каждого из которых есть свое BGP-соединение. Плейбук может проверить все ‘эти пять соединений, и если работает хотя бы одно из них, а не все пять, сообщить, что все в порядке. Просто запомните, что any – это логическое ИЛИ, а all – логическое И.
Негативные условия: строим обратную логику
Что дальше
Ознакомитесь с документацией по работе с выводом команд в сетевых модулях. Там приводятся полезные примеры использования ge, le и других условий при работе с выводом в формате JSON на конкретных сетевых платформах.
В настоящее время нет ошибок, и он работает нормально. Однако он не отображает вывод на консоль. Я столкнулся с этим с другими игровыми книгами и обошел его, добавив следующую пьесу в учебник:
и он выводит результат. Однако я попытался сделать то же самое в выше, и он говорит, что переменная была undefined (код не показано, потому что это не сработало).
Кто-нибудь знает, как лучше получить вывод для печати на консоль без использования -debug ? Любые важные ссылки были бы оценены.
Всякая задача, выполняемая при запуске, может сохранить результаты в переменной. Для этого вам нужно указать, какую переменную сохранить. Это можно сделать с параметром register , независимо от используемого модуля.
После сохранения значения переменной вы можете использовать ее позже в любой из последующих задач. Например, если вы хотите получить стандартный вывод определенной задачи, вы можете написать следующее:
Здесь register указывает возможность сохранения ответа модуля в переменную shell_result , а затем мы используем модуль debug для вывода переменной.
Пример запуска будет выглядеть следующим образом:
Ответы могут содержать несколько полей. stdout_lines одно из полей по умолчанию, которое можно ожидать от ответа модуля.
Не все поля доступны из всех модулей, например, для модуля, который ничего не возвращает к стандарту, вы не ожидали бы ничего в значениях stdout или stdout_lines , однако поле msg могут быть заполнены в этом случае. Также есть некоторые модули, где вы можете найти что-то в нестандартной переменной, для этого вы можете попытаться проконсультироваться с документацией модуля для этих нестандартных значений возврата.
В качестве альтернативы вы можете увеличить уровень детализации загружаемого файла. Вы можете выбирать между различными уровнями детализации: -v , -vvv и -vvvv . Например, при запуске playbook с подробностью ( -vvv ) вы получите следующее:
Как вы можете видеть, это позволит распечатать ответ каждого из модулей и всех доступных полей. Вы можете видеть, что stdout_lines доступен, и это то, что мы ожидаем.
Чтобы ответить на ваш основной вопрос о модуле jenkins_script , если вы проверите его документацию, вы увидите, что он возвращает результат в output , поэтому вы можете попробовать следующее:
Читайте также: