Русский
Русский
English
Статистика
Реклама

Продолжаем прокачивать Ansible

Поводом для этой статьи послужил пост в чате @pro_ansible:

Vladislav ? Shishkov, [17.02.21 20:59]Господа, есть два вопроса, касаются кастомной долгой операции, например, бекапа: 1. Можно ли через ансибл прикрутить прогрессбар выполнения кастомного баша? (если через плагин, то пните в какой-нибудь пример или документацию плиз) 2. Вроде хочется для этого баша написать плагин, но встает вопрос, как быть и как решать моменты выполнения, которые идемпотентны?

Беглый поиск по задворкам памяти ничего подходящего не подсказал. Тем не менее, я точно вспомнил, что код Ansible легко читаемый, и искаропки поддерживает расширение как плагинами, так и обычными Python-модулями. А раз так, то ничего не мешает в очередной раз раздвинуть границы возможного. Hold my beer!...

Понятно, что стандартный Ansible уже умеет делать оба шага, только вот полученный выхлоп собирается в единое целое и передаётся на управляющий хост уже по завершению процесса, а мы хотим это сделать в реальном времени. Следовательно, можно как минимум посмотреть на существующую реализацию, а как максимум - каким-то образом переиспользовать существующий код.

Исходный вопрос можно свести к двум простейшим шагам:

  1. Захватить stdout команды на целевом хосте

  2. Передать его на управляющий хост.

Передаём данные на управляющий хост

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

Код на Python
# добавляем куда-нибудь сюда:# https://github.com/ansible/ansible/blob/5078a0baa26e0eb715e86c93ec32af6bc4022e45/lib/ansible/plugins/connection/ssh.py#L662self._add_args(    b_command,    (b"-R", b"127.0.0.1:33333:" + to_bytes(self._play_context.remote_addr, errors='surrogate_or_strict', nonstring='simplerepr') + b":33335"),    u"ANSIBLE_STREAMING/streaming set")

Как это работает? При сборке аргументов командной строки для установления ssh-соединения эта конструкция предоставит нам на целевом хосте порт 33333 по адресу 127.0.0.1, который будет туннелировать входящие соединения на контроллер - прямиком на порт 33335.

Для простоты используем netcat (ну правда, ну что за статья без котиков?): nc -lk 33335.

В этот момент, кстати, уже можно запустить Ansible и проверить, что туннель работает так, как следует: хотя пока по нему ничего и не передаётся, мы уже можем на целевом хосте зайти в консоль и выполнить nc 127.0.0.1 33333, введя какую-нибудь фразу и увидев её как результат работы команды выше.

Перехватываем stdout

Полдела сделано - идём дальше. Мы хотим перехватить stdout какой-то команды - по логике работы Ansible нам подойдёт модуль shell. Забавной, что он оказался пустышкой - в нём ни строчки кода, кроме документации и примеров, зато находим в нём отсылку к модулю command. С ним всё оказалось хорошо, кроме того факта, что нужная функция в нём напрямую не описана, хотя и использована. Но это уже было почти попадание в яблочко, потому что в итоге она нашлась в другом файле.

Под мысленное просто добавь воды просто добавляем щепотку своего кода:

Опять код
# в начале basic.py, рядом с прочими import'ами import socket# в функции run_command - где-нибудь тут:# https://github.com/ansible/ansible/blob/5078a0baa26e0eb715e86c93ec32af6bc4022e45/lib/ansible/module_utils/basic.py#L2447clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);clientSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)clientSocket.connect(("127.0.0.1",33333));# в функции run_command - где-нибудь тут:# https://github.com/ansible/ansible/blob/5078a0baa26e0eb715e86c93ec32af6bc4022e45/lib/ansible/module_utils/basic.py#L2455clientSocket.send(b_chunk);# в функции run_command - где-нибудь тут# https://github.com/ansible/ansible/blob/5078a0baa26e0eb715e86c93ec32af6bc4022e45/lib/ansible/module_utils/basic.py#L2481clientSocket.close()

Собираем воедино и запускаем

Осталось сделать что? Правильно, определиться со способом подключения изменённых модулей в стоковый Ansible. На всякий случай напоминаю: мы поправили один connection plugin, и один модуль из стандартной библиотеки Ansible. Новичкам в этом деле могу рекомендовать статью хабраюзера chemtech с расшифровкой моего доклада на Стачке-2019 (там как раз в том числе объясняется, какие Python-модули куда складывать), ну а опытным бойцам эти пояснения вроде и не нужны :-)

Итак, время Ч. Результат в виде статичной картинки не очень показателен, поэтому я настроил tmux и запустил запись скринкаста.

Для внимательных зрителей скринкаста

В анимации можете увидеть два полезных побочных эффекта:

  • Теперь мы видим stdout всех не-Python процессов, которые запускаются Ansible'ом на целевом хосте - например, тех, что запускаются при сборе фактов;

  • Настройки переиспользования ssh-соединений из другой моей статьи позволяют получать этот самый stdout от удалённой команды уже после отключения Ansible от хоста.

Хотите ко мне на тренинг по Ansible?

Раз уж вы здесь - значит, вам как минимум интересно то, что я пишу об Ansible. Так вот, у меня есть опыт ведения такого тренинга внутри компании для коллег.

В прошедшем году я всерьёз начал задумываться о том, чтобы начать вести свой собственный тренинг по этому инструменту для всех желающих, поэтому предлагаю пройти опрос.

Источник: habr.com
К списку статей
Опубликовано: 22.02.2021 06:06:33
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Системное администрирование

Python

*nix

Серверное администрирование

Devops

Ansible

Тегиниктонечитает

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru