From f45ae8b64eb7745158500d1169efb729e7318a96 Mon Sep 17 00:00:00 2001 From: Sergey Antropoff Date: Wed, 22 Oct 2025 15:33:53 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=A3=D0=B1=D1=80=D0=B0=D0=BD=D1=8B=20?= =?UTF-8?q?=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=BF?= =?UTF-8?q?=D1=83=D0=BD=D0=BA=D1=82=D1=8B=20'interactive'=20=D0=B8=20?= =?UTF-8?q?=D0=B2=D1=81=D0=B5=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=D1=8B=20=D1=87?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B7=20whiptail=20=D0=B4=D0=B8=D0=B0=D0=BB?= =?UTF-8?q?=D0=BE=D0=B3=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Убран пункт '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 --- Makefile | 161 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 139 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index a4cba6d..25dd329 100644 --- a/Makefile +++ b/Makefile @@ -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 \