feat: Убраны отдельные пункты 'interactive' и все операции сделаны через whiptail диалоги

- Убран пункт 'interactive' из главного меню
- Убран пункт 'interactive' из меню пресетов
- Убран пункт 'interactive' из меню ролей
- Создание пресетов теперь полностью интерактивное через whiptail
- Создание ролей теперь полностью интерактивное через whiptail

Создание пресетов через whiptail:
- Интерактивный ввод имени пресета
- Интерактивный ввод описания
- Выбор количества хостов
- Выбор семейства ОС (debian/redhat/mixed)
- Выбор функций (docker, dind, k8s, istio, monitoring, chaos)
- Автоматическая генерация YAML файла пресета
- Информативное сообщение об успехе

Создание ролей через whiptail:
- Интерактивный ввод имени роли
- Интерактивный ввод описания
- Выбор пакета для установки
- Выбор сервиса для управления
- Выбор поддерживаемых платформ (debian/redhat)
- Ввод тегов роли
- Автоматическая генерация полной структуры роли
- Создание универсальных задач для Debian и RHEL
- Создание handlers, defaults, meta файлов
- Информативное сообщение об успехе

Преимущества:
- Все операции через единый интерфейс whiptail
- Нет дублирования функциональности
- Интерактивный ввод всех параметров
- Автоматическая генерация файлов
- Универсальные роли для разных ОС
- Информативные сообщения об успехе

Автор: Сергей Антропов
Сайт: https://devops.org.ru
This commit is contained in:
2025-10-22 15:33:53 +03:00
parent 3fe419f38e
commit f45ae8b64e

161
Makefile
View File

@@ -79,7 +79,7 @@ help: ## Показать справку по всем командам
menu: check-whiptail ## Интерактивное главное меню
@while true; do \
CHOICE=$$(whiptail --title "Ansible Template - Универсальная лаборатория" \
--menu "Выберите действие:" 20 60 13 \
--menu "Выберите действие:" 20 60 12 \
"lab" "🧪 Управление лабораторией" \
"kube" "☸️ Управление Kubernetes" \
"preset" "📋 Управление пресетами" \
@@ -89,7 +89,6 @@ menu: check-whiptail ## Интерактивное главное меню
"lint" "🔍 Проверка синтаксиса" \
"snapshot" "📸 Снимки лаборатории" \
"cleanup" "🧹 Очистка данных" \
"interactive" "🎯 Интерактивные команды" \
"docs" "📚 Документация" \
"help" "❓ Помощь и справка" \
"exit" "🚪 Выход" \
@@ -108,7 +107,6 @@ menu: check-whiptail ## Интерактивное главное меню
"lint") make menu-lint;; \
"snapshot") make menu-snapshot;; \
"cleanup") make menu-cleanup;; \
"interactive") make menu-interactive;; \
"docs") make menu-docs;; \
"help") make menu-help;; \
esac; \
@@ -260,13 +258,12 @@ menu-kube: check-whiptail ## Меню управления Kubernetes
.PHONY: menu-preset
menu-preset: check-whiptail ## Меню управления пресетами
@CHOICE=$$(whiptail --title "📋 Управление пресетами" \
--menu "Выберите действие:" 15 50 8 \
--menu "Выберите действие:" 15 50 7 \
"list" "📋 Список пресетов" \
"create" " Создать пресет" \
"edit" "✏️ Редактировать пресет" \
"test" "🧪 Тестировать пресет" \
"copy" "📋 Копировать пресет" \
"interactive" "🎯 Интерактивное создание" \
"back" "⬅️ Назад" \
3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \
@@ -280,15 +277,49 @@ menu-preset: check-whiptail ## Меню управления пресетами
whiptail --title "⚠️ Предупреждение" --msgbox "Пресеты не найдены или недоступны." 8 50; \
fi;; \
"create") \
PRESET_NAME=$$(whiptail --inputbox "Введите имя нового пресета:" 8 50 "my-preset" 3>&1 1>&2 2>&3); \
if [ $$? -eq 0 ] && [ -n "$$PRESET_NAME" ]; then \
echo "$(BLUE) Создание пресета: $$PRESET_NAME$(RESET)"; \
if make preset create NAME="$$PRESET_NAME"; then \
whiptail --title "✅ Успех" --msgbox "Пресет $$PRESET_NAME успешно создан!" 8 50; \
echo "$(CYAN)🎯 Создание нового пресета лаборатории$(RESET)"; \
PRESET_NAME=$$(whiptail --inputbox "Введите имя пресета (например: my-lab):" 8 50 "my-lab" 3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ]; then exit 0; fi; \
PRESET_DESC=$$(whiptail --inputbox "Введите описание пресета:" 8 50 "Мой лабораторный пресет" 3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ]; then exit 0; fi; \
HOST_COUNT=$$(whiptail --inputbox "Количество хостов:" 8 50 "3" 3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ]; then exit 0; fi; \
OS_FAMILY=$$(whiptail --menu "Выберите семейство ОС:" 15 50 4 "debian" "Debian/Ubuntu" "redhat" "RHEL/CentOS" "mixed" "Смешанное" 3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ]; then exit 0; fi; \
FEATURES=$$(whiptail --checklist "Выберите функции:" 15 50 6 "docker" "Docker" off "dind" "Docker-in-Docker" off "k8s" "Kubernetes" off "istio" "Istio" off "monitoring" "Мониторинг" off "chaos" "Chaos Engineering" off 3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ]; then exit 0; fi; \
echo "$(BLUE)📝 Создание пресета: $$PRESET_NAME$(RESET)"; \
mkdir -p molecule/presets; \
echo "---" > molecule/presets/$$PRESET_NAME.yml; \
echo "# Пресет: $$PRESET_DESC" >> molecule/presets/$$PRESET_NAME.yml; \
echo "# Автор: $(AUTHOR)" >> molecule/presets/$$PRESET_NAME.yml; \
echo "# Сайт: $(SITE)" >> molecule/presets/$$PRESET_NAME.yml; \
echo "" >> molecule/presets/$$PRESET_NAME.yml; \
echo "hosts:" >> molecule/presets/$$PRESET_NAME.yml; \
for i in $$(seq 1 $$HOST_COUNT); do \
echo " - name: host$$i" >> molecule/presets/$$PRESET_NAME.yml; \
if [ "$$OS_FAMILY" = "debian" ]; then \
echo " family: debian" >> molecule/presets/$$PRESET_NAME.yml; \
elif [ "$$OS_FAMILY" = "redhat" ]; then \
echo " family: redhat" >> molecule/presets/$$PRESET_NAME.yml; \
else \
whiptail --title "❌ Ошибка" --msgbox "Ошибка при создании пресета $$PRESET_NAME." 8 50; \
if [ $$((i % 2)) -eq 0 ]; then \
echo " family: debian" >> molecule/presets/$$PRESET_NAME.yml; \
else \
echo " family: redhat" >> molecule/presets/$$PRESET_NAME.yml; \
fi; \
fi; \
fi;; \
echo " groups: [all]" >> molecule/presets/$$PRESET_NAME.yml; \
done; \
echo "" >> molecule/presets/$$PRESET_NAME.yml; \
echo "features:" >> molecule/presets/$$PRESET_NAME.yml; \
echo " docker: $$(echo $$FEATURES | grep -q docker && echo 'true' || echo 'false')" >> molecule/presets/$$PRESET_NAME.yml; \
echo " dind: $$(echo $$FEATURES | grep -q dind && echo 'true' || echo 'false')" >> molecule/presets/$$PRESET_NAME.yml; \
echo " k8s: $$(echo $$FEATURES | grep -q k8s && echo 'true' || echo 'false')" >> molecule/presets/$$PRESET_NAME.yml; \
echo " istio: $$(echo $$FEATURES | grep -q istio && echo 'true' || echo 'false')" >> molecule/presets/$$PRESET_NAME.yml; \
echo " monitoring: $$(echo $$FEATURES | grep -q monitoring && echo 'true' || echo 'false')" >> molecule/presets/$$PRESET_NAME.yml; \
echo " chaos: $$(echo $$FEATURES | grep -q chaos && echo 'true' || echo 'false')" >> molecule/presets/$$PRESET_NAME.yml; \
whiptail --title "✅ Успех" --msgbox "Пресет $$PRESET_NAME создан: molecule/presets/$$PRESET_NAME.yml\n\nИспользование: make lab up PRESET=$$PRESET_NAME" 10 70;; \
"edit") \
PRESET_NAME=$$(whiptail --inputbox "Введите имя пресета для редактирования:" 8 50 "" 3>&1 1>&2 2>&3); \
if [ $$? -eq 0 ] && [ -n "$$PRESET_NAME" ]; then \
@@ -340,7 +371,6 @@ menu-role: check-whiptail ## Меню управления ролями
"lint" "🔍 Проверка синтаксиса" \
"deploy" "🚀 Развертывание ролей" \
"playbook" "📝 Управление playbooks" \
"interactive" "🎯 Интерактивное создание" \
"back" "⬅️ Назад" \
3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \
@@ -354,15 +384,102 @@ menu-role: check-whiptail ## Меню управления ролями
whiptail --title "⚠️ Предупреждение" --msgbox "Роли не найдены или недоступны." 8 50; \
fi;; \
"create") \
ROLE_NAME=$$(whiptail --inputbox "Введите имя новой роли:" 8 50 "my-role" 3>&1 1>&2 2>&3); \
if [ $$? -eq 0 ] && [ -n "$$ROLE_NAME" ]; then \
echo "$(BLUE) Создание роли: $$ROLE_NAME$(RESET)"; \
if make role create NAME="$$ROLE_NAME"; then \
whiptail --title "✅ Успех" --msgbox "Роль $$ROLE_NAME успешно создана!" 8 50; \
else \
whiptail --title "❌ Ошибка" --msgbox "Ошибка при создании роли $$ROLE_NAME." 8 50; \
fi; \
fi;; \
echo "$(CYAN)🎯 Создание новой Ansible роли$(RESET)"; \
ROLE_NAME=$$(whiptail --inputbox "Введите имя роли (например: nginx):" 8 50 "nginx" 3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ]; then exit 0; fi; \
ROLE_DESC=$$(whiptail --inputbox "Введите описание роли:" 8 50 "Установка и настройка Nginx" 3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ]; then exit 0; fi; \
PACKAGE_NAME=$$(whiptail --inputbox "Имя пакета для установки:" 8 50 "nginx" 3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ]; then exit 0; fi; \
SERVICE_NAME=$$(whiptail --inputbox "Имя сервиса для управления:" 8 50 "nginx" 3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ]; then exit 0; fi; \
PLATFORMS=$$(whiptail --checklist "Поддерживаемые платформы:" 15 50 4 "debian" "Debian/Ubuntu" on "redhat" "RHEL/CentOS" on 3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ]; then exit 0; fi; \
TAGS=$$(whiptail --inputbox "Теги роли (через запятую):" 8 50 "web,nginx,http" 3>&1 1>&2 2>&3); \
if [ $$? -ne 0 ]; then exit 0; fi; \
echo "$(BLUE)📝 Создание роли: $$ROLE_NAME$(RESET)"; \
mkdir -p roles/$$ROLE_NAME/{tasks,handlers,templates,files,vars,defaults,meta}; \
echo "---" > roles/$$ROLE_NAME/meta/main.yml; \
echo "galaxy_info:" >> roles/$$ROLE_NAME/meta/main.yml; \
echo " author: $(AUTHOR)" >> roles/$$ROLE_NAME/meta/main.yml; \
echo " description: $$ROLE_DESC" >> roles/$$ROLE_NAME/meta/main.yml; \
echo " company: $(SITE)" >> roles/$$ROLE_NAME/meta/main.yml; \
echo " license: MIT" >> roles/$$ROLE_NAME/meta/main.yml; \
echo " min_ansible_version: 2.9" >> roles/$$ROLE_NAME/meta/main.yml; \
echo " platforms:" >> roles/$$ROLE_NAME/meta/main.yml; \
if echo "$$PLATFORMS" | grep -q debian; then \
echo " - name: Ubuntu" >> roles/$$ROLE_NAME/meta/main.yml; \
echo " versions: [18.04, 20.04, 22.04]" >> roles/$$ROLE_NAME/meta/main.yml; \
echo " - name: Debian" >> roles/$$ROLE_NAME/meta/main.yml; \
echo " versions: [10, 11, 12]" >> roles/$$ROLE_NAME/meta/main.yml; \
fi; \
if echo "$$PLATFORMS" | grep -q redhat; then \
echo " - name: EL" >> roles/$$ROLE_NAME/meta/main.yml; \
echo " versions: [7, 8, 9]" >> roles/$$ROLE_NAME/meta/main.yml; \
fi; \
echo " galaxy_tags: [$$TAGS]" >> roles/$$ROLE_NAME/meta/main.yml; \
echo "" >> roles/$$ROLE_NAME/meta/main.yml; \
echo "dependencies: []" >> roles/$$ROLE_NAME/meta/main.yml; \
echo "---" > roles/$$ROLE_NAME/defaults/main.yml; \
echo "# Переменные по умолчанию для роли $$ROLE_NAME" >> roles/$$ROLE_NAME/defaults/main.yml; \
echo "# Автор: $(AUTHOR)" >> roles/$$ROLE_NAME/defaults/main.yml; \
echo "# Сайт: $(SITE)" >> roles/$$ROLE_NAME/defaults/main.yml; \
echo "" >> roles/$$ROLE_NAME/defaults/main.yml; \
echo "$$ROLE_NAME_package: $$PACKAGE_NAME" >> roles/$$ROLE_NAME/defaults/main.yml; \
echo "$$ROLE_NAME_service: $$SERVICE_NAME" >> roles/$$ROLE_NAME/defaults/main.yml; \
echo "$$ROLE_NAME_enabled: true" >> roles/$$ROLE_NAME/defaults/main.yml; \
echo "$$ROLE_NAME_started: true" >> roles/$$ROLE_NAME/defaults/main.yml; \
echo "---" > roles/$$ROLE_NAME/tasks/main.yml; \
echo "# Основные задачи роли $$ROLE_NAME" >> roles/$$ROLE_NAME/tasks/main.yml; \
echo "# Автор: $(AUTHOR)" >> roles/$$ROLE_NAME/tasks/main.yml; \
echo "# Сайт: $(SITE)" >> roles/$$ROLE_NAME/tasks/main.yml; \
echo "" >> roles/$$ROLE_NAME/tasks/main.yml; \
echo "- name: Включить задачи для Debian/Ubuntu" >> roles/$$ROLE_NAME/tasks/main.yml; \
echo " import_tasks: debian.yml" >> roles/$$ROLE_NAME/tasks/main.yml; \
echo " when: ansible_os_family == 'Debian'" >> roles/$$ROLE_NAME/tasks/main.yml; \
echo "" >> roles/$$ROLE_NAME/tasks/main.yml; \
echo "- name: Включить задачи для RHEL/CentOS" >> roles/$$ROLE_NAME/tasks/main.yml; \
echo " import_tasks: redhat.yml" >> roles/$$ROLE_NAME/tasks/main.yml; \
echo " when: ansible_os_family == 'RedHat'" >> roles/$$ROLE_NAME/tasks/main.yml; \
echo "---" > roles/$$ROLE_NAME/tasks/debian.yml; \
echo "# Задачи для Debian/Ubuntu" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo "" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo "- name: Обновить кэш пакетов" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo " apt:" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo " update_cache: yes" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo " cache_valid_time: 3600" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo "" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo "- name: Установить пакет $$PACKAGE_NAME" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo " apt:" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo " name: \"{{ $$ROLE_NAME_package }}\"" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo " state: present" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo "" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo "- name: Запустить и включить сервис $$SERVICE_NAME" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo " systemd:" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo " name: \"{{ $$ROLE_NAME_service }}\"" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo " enabled: \"{{ $$ROLE_NAME_enabled }}\"" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo " state: \"{{ 'started' if $$ROLE_NAME_started else 'stopped' }}\"" >> roles/$$ROLE_NAME/tasks/debian.yml; \
echo "---" > roles/$$ROLE_NAME/tasks/redhat.yml; \
echo "# Задачи для RHEL/CentOS" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo "" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo "- name: Установить пакет $$PACKAGE_NAME" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo " yum:" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo " name: \"{{ $$ROLE_NAME_package }}\"" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo " state: present" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo "" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo "- name: Запустить и включить сервис $$SERVICE_NAME" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo " systemd:" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo " name: \"{{ $$ROLE_NAME_service }}\"" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo " enabled: \"{{ $$ROLE_NAME_enabled }}\"" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo " state: \"{{ 'started' if $$ROLE_NAME_started else 'stopped' }}\"" >> roles/$$ROLE_NAME/tasks/redhat.yml; \
echo "---" > roles/$$ROLE_NAME/handlers/main.yml; \
echo "# Обработчики роли $$ROLE_NAME" >> roles/$$ROLE_NAME/handlers/main.yml; \
echo "" >> roles/$$ROLE_NAME/handlers/main.yml; \
echo "- name: Перезапустить $$SERVICE_NAME" >> roles/$$ROLE_NAME/handlers/main.yml; \
echo " systemd:" >> roles/$$ROLE_NAME/handlers/main.yml; \
echo " name: \"{{ $$ROLE_NAME_service }}\"" >> roles/$$ROLE_NAME/handlers/main.yml; \
echo " state: restarted" >> roles/$$ROLE_NAME/handlers/main.yml; \
whiptail --title "✅ Успех" --msgbox "Роль $$ROLE_NAME создана в roles/$$ROLE_NAME/\n\nСтруктура:\n- tasks/ (основные задачи)\n- handlers/ (обработчики)\n- defaults/ (переменные)\n- meta/ (метаданные)\n\nИспользование: make role test NAME=$$ROLE_NAME" 15 70;; \
"edit") \
ROLE_NAME=$$(whiptail --inputbox "Введите имя роли для редактирования:" 8 50 "" 3>&1 1>&2 2>&3); \
if [ $$? -eq 0 ] && [ -n "$$ROLE_NAME" ]; then \