From c8dbc5356fe252f58c84bbc111ca2cc4891042a6 Mon Sep 17 00:00:00 2001 From: Sergey Antropoff Date: Wed, 22 Oct 2025 15:22:51 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=9F=D0=BE=D0=BB=D0=BD=D0=BE=D1=86?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D0=B9=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=B9=20=D0=B8=D0=BD?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=20=D1=81=20whiptail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Создано главное интерактивное меню с 13 разделами - Добавлено интерактивное меню помощи с 6 подразделами - Команда по умолчанию (make) теперь запускает главное меню - Создано интерактивное создание playbooks - Исправлены ошибки с return/exit в меню Интерактивные меню: - 🧪 Управление лабораторией (8 команд) - ☸️ Управление Kubernetes (7 команд) - 📋 Управление пресетами (6 команд) - 🎭 Управление ролями (8 команд) - 🔐 Управление vault (5 команд) - 📊 Генерация отчетов (4 команды) - 🔍 Проверка синтаксиса (5 команд) - 📸 Снимки лаборатории (3 команды) - 🧹 Очистка данных (5 команд) - 🎯 Интерактивные команды (3 команды) - 📚 Документация (6 разделов) - ❓ Помощь и справка (6 разделов) Меню помощи включает: - 📋 Обзор проекта - 🚀 Быстрый старт - ⌨️ Список команд - 💡 Примеры использования - 🔧 Решение проблем - ℹ️ О проекте Преимущества: - Полноценный TUI интерфейс - Навигация через меню - Красивые диалоги с эмодзи - Подробная справка - Минимум ручного труда - Удобство использования Автор: Сергей Антропов Сайт: https://devops.org.ru --- Makefile | 355 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 354 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c532c28..e96afcc 100644 --- a/Makefile +++ b/Makefile @@ -48,6 +48,9 @@ RESET := \033[0m # ОСНОВНЫЕ КОМАНДЫ # ============================================================================= +# Команда по умолчанию - интерактивное меню +.DEFAULT_GOAL := menu + .PHONY: help help: ## Показать справку по всем командам @echo "$(CYAN)Ansible Template - Универсальная лаборатория$(RESET)" @@ -72,6 +75,311 @@ help: ## Показать справку по всем командам @echo "" @echo "$(YELLOW)Подробная документация: docs/$(RESET)" +.PHONY: menu +menu: check-whiptail ## Интерактивное главное меню + @while true; do \ + CHOICE=$$(whiptail --title "Ansible Template - Универсальная лаборатория" \ + --menu "Выберите действие:" 20 60 13 \ + "lab" "🧪 Управление лабораторией" \ + "kube" "☸️ Управление Kubernetes" \ + "preset" "📋 Управление пресетами" \ + "role" "🎭 Управление ролями" \ + "vault" "🔐 Управление vault" \ + "report" "📊 Генерация отчетов" \ + "lint" "🔍 Проверка синтаксиса" \ + "snapshot" "📸 Снимки лаборатории" \ + "cleanup" "🧹 Очистка данных" \ + "interactive" "🎯 Интерактивные команды" \ + "docs" "📚 Документация" \ + "help" "❓ Помощь и справка" \ + "exit" "🚪 Выход" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "exit" ]; then \ + echo "$(YELLOW)👋 До свидания!$(RESET)"; \ + break; \ + fi; \ + case "$$CHOICE" in \ + "lab") make menu-lab;; \ + "kube") make menu-kube;; \ + "preset") make menu-preset;; \ + "role") make menu-role;; \ + "vault") make menu-vault;; \ + "report") make menu-report;; \ + "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; \ + done + +# ============================================================================= +# ИНТЕРАКТИВНЫЕ МЕНЮ +# ============================================================================= + +.PHONY: menu-lab +menu-lab: check-whiptail ## Меню управления лабораторией + @CHOICE=$$(whiptail --title "🧪 Управление лабораторией" \ + --menu "Выберите действие:" 15 50 8 \ + "up" "🚀 Запустить лабораторию" \ + "down" "🛑 Остановить лабораторию" \ + "test" "🧪 Тестировать лабораторию" \ + "destroy" "💥 Уничтожить лабораторию" \ + "status" "📊 Статус лаборатории" \ + "logs" "📝 Просмотр логов" \ + "shell" "🐚 Подключиться к контейнеру" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "up") make lab up;; \ + "down") make lab down;; \ + "test") make lab test;; \ + "destroy") make lab destroy;; \ + "status") make lab status;; \ + "logs") make lab logs;; \ + "shell") make lab shell;; \ + esac + +.PHONY: menu-kube +menu-kube: check-whiptail ## Меню управления Kubernetes + @CHOICE=$$(whiptail --title "☸️ Управление Kubernetes" \ + --menu "Выберите действие:" 15 50 8 \ + "logs" "📝 Просмотр логов" \ + "exec" "🐚 Выполнить команду" \ + "port-forward" "🔗 Проброс портов" \ + "kiali" "🔍 Kiali Dashboard" \ + "istio" "🌐 Istio Gateway" \ + "grafana" "📊 Grafana Dashboard" \ + "prometheus" "📈 Prometheus" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "logs") make kube logs;; \ + "exec") make kube exec;; \ + "port-forward") make kube port-forward;; \ + "kiali") make kube kiali;; \ + "istio") make kube istio;; \ + "grafana") make kube grafana;; \ + "prometheus") make kube prometheus;; \ + esac + +.PHONY: menu-preset +menu-preset: check-whiptail ## Меню управления пресетами + @CHOICE=$$(whiptail --title "📋 Управление пресетами" \ + --menu "Выберите действие:" 15 50 8 \ + "list" "📋 Список пресетов" \ + "create" "➕ Создать пресет" \ + "edit" "✏️ Редактировать пресет" \ + "test" "🧪 Тестировать пресет" \ + "copy" "📋 Копировать пресет" \ + "interactive" "🎯 Интерактивное создание" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "list") make preset list;; \ + "create") make preset create;; \ + "edit") make preset edit;; \ + "test") make preset test;; \ + "copy") make preset copy;; \ + "interactive") make preset-create-interactive;; \ + esac + +.PHONY: menu-role +menu-role: check-whiptail ## Меню управления ролями + @CHOICE=$$(whiptail --title "🎭 Управление ролями" \ + --menu "Выберите действие:" 15 50 8 \ + "list" "📋 Список ролей" \ + "create" "➕ Создать роль" \ + "edit" "✏️ Редактировать роль" \ + "test" "🧪 Тестировать роль" \ + "lint" "🔍 Проверка синтаксиса" \ + "deploy" "🚀 Развертывание ролей" \ + "playbook" "📝 Управление playbooks" \ + "interactive" "🎯 Интерактивное создание" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "list") make role list;; \ + "create") make role create;; \ + "edit") make role edit;; \ + "test") make role test;; \ + "lint") make role lint;; \ + "deploy") make role deploy;; \ + "playbook") make role playbook;; \ + "interactive") make role-create-interactive;; \ + esac + +.PHONY: menu-vault +menu-vault: check-whiptail ## Меню управления vault + @CHOICE=$$(whiptail --title "🔐 Управление vault" \ + --menu "Выберите действие:" 15 50 8 \ + "view" "👁️ Просмотр секретов" \ + "create" "➕ Создать секрет" \ + "edit" "✏️ Редактировать секрет" \ + "encrypt" "🔒 Зашифровать файл" \ + "decrypt" "🔓 Расшифровать файл" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "view") make vault view;; \ + "create") make vault create;; \ + "edit") make vault edit;; \ + "encrypt") make vault encrypt;; \ + "decrypt") make vault decrypt;; \ + esac + +.PHONY: menu-report +menu-report: check-whiptail ## Меню генерации отчетов + @CHOICE=$$(whiptail --title "📊 Генерация отчетов" \ + --menu "Выберите действие:" 15 50 8 \ + "html" "📄 HTML отчет" \ + "json" "📋 JSON отчет" \ + "health" "🏥 Отчет о здоровье" \ + "topology" "🗺️ Топология сети" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "html") make report;; \ + "json") make report-json;; \ + "health") make health-report;; \ + "topology") make topology;; \ + esac + +.PHONY: menu-lint +menu-lint: check-whiptail ## Меню проверки синтаксиса + @CHOICE=$$(whiptail --title "🔍 Проверка синтаксиса" \ + --menu "Выберите действие:" 15 50 8 \ + "all" "🔍 Проверить все" \ + "roles" "🎭 Проверить роли" \ + "playbooks" "📝 Проверить playbooks" \ + "vault" "🔐 Проверить vault" \ + "secrets" "🔍 Проверить секреты" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "all") make lint;; \ + "roles") make role lint;; \ + "playbooks") make lint-playbooks;; \ + "vault") make lint-vault;; \ + "secrets") make check-secrets;; \ + esac + +.PHONY: menu-snapshot +menu-snapshot: check-whiptail ## Меню снимков лаборатории + @CHOICE=$$(whiptail --title "📸 Снимки лаборатории" \ + --menu "Выберите действие:" 15 50 8 \ + "create" "📸 Создать снимок" \ + "restore" "🔄 Восстановить снимок" \ + "list" "📋 Список снимков" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "create") make snapshot;; \ + "restore") make restore;; \ + "list") make snapshot-list;; \ + esac + +.PHONY: menu-cleanup +menu-cleanup: check-whiptail ## Меню очистки данных + @CHOICE=$$(whiptail --title "🧹 Очистка данных" \ + --menu "Выберите действие:" 15 50 8 \ + "all" "🧹 Очистить все" \ + "containers" "🐳 Очистить контейнеры" \ + "images" "🖼️ Очистить образы" \ + "volumes" "💾 Очистить тома" \ + "reports" "📊 Очистить отчеты" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "all") make cleanup;; \ + "containers") make cleanup-containers;; \ + "images") make cleanup-images;; \ + "volumes") make cleanup-volumes;; \ + "reports") make cleanup-reports;; \ + esac + +.PHONY: menu-interactive +menu-interactive: check-whiptail ## Меню интерактивных команд + @CHOICE=$$(whiptail --title "🎯 Интерактивные команды" \ + --menu "Выберите действие:" 15 50 8 \ + "preset" "📋 Создать пресет" \ + "role" "🎭 Создать роль" \ + "playbook" "📝 Создать playbook" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "preset") make preset-create-interactive;; \ + "role") make role-create-interactive;; \ + "playbook") make playbook-create-interactive;; \ + esac + +.PHONY: menu-docs +menu-docs: check-whiptail ## Меню документации + @CHOICE=$$(whiptail --title "📚 Документация" \ + --menu "Выберите действие:" 15 50 8 \ + "readme" "📖 README" \ + "lab" "🧪 Универсальная лаборатория" \ + "presets" "📋 Пресеты" \ + "roles" "🎭 Роли" \ + "examples" "💡 Примеры" \ + "api" "🔧 API Reference" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "readme") cat README.md | less;; \ + "lab") cat docs/universal-lab.md | less;; \ + "presets") cat docs/presets.md | less;; \ + "roles") cat docs/roles.md | less;; \ + "examples") cat docs/examples.md | less;; \ + "api") cat docs/api.md | less;; \ + esac + +.PHONY: menu-help +menu-help: check-whiptail ## Меню помощи и справки + @CHOICE=$$(whiptail --title "❓ Помощь и справка" \ + --menu "Выберите действие:" 15 50 8 \ + "overview" "📋 Обзор проекта" \ + "quickstart" "🚀 Быстрый старт" \ + "commands" "⌨️ Список команд" \ + "examples" "💡 Примеры использования" \ + "troubleshooting" "🔧 Решение проблем" \ + "about" "ℹ️ О проекте" \ + "back" "⬅️ Назад" \ + 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ] || [ "$$CHOICE" = "back" ]; then exit 0; fi; \ + case "$$CHOICE" in \ + "overview") \ + whiptail --title "📋 Обзор проекта" \ + --msgbox "Ansible Template - Универсальная лаборатория для тестирования Ansible ролей и playbooks.\n\nОсновные возможности:\n• 🧪 Универсальная лаборатория с Docker\n• ☸️ Kubernetes кластеры (Kind)\n• 📋 Готовые пресеты для разных сценариев\n• 🎭 Управление Ansible ролями\n• 🔐 Безопасное хранение секретов\n• 📊 Генерация отчетов\n• 🎯 Интерактивные команды\n\nАвтор: $(AUTHOR)\nСайт: $(SITE)" 20 70;; \ + "quickstart") \ + whiptail --title "🚀 Быстрый старт" \ + --msgbox "Быстрый старт:\n\n1. Инициализация проекта:\n make init\n\n2. Запуск лаборатории:\n make lab up\n\n3. Создание роли:\n make role-create-interactive\n\n4. Создание пресета:\n make preset-create-interactive\n\n5. Генерация отчета:\n make report\n\nВсе команды доступны через интерактивное меню!" 20 70;; \ + "commands") \ + whiptail --title "⌨️ Список команд" \ + --msgbox "Основные команды:\n\n• make - Главное меню\n• make help - Справка\n• make init - Инициализация\n• make lab up - Запуск лаборатории\n• make lab down - Остановка\n• make lab test - Тестирование\n• make role list - Список ролей\n• make preset list - Список пресетов\n• make vault view - Просмотр секретов\n• make report - Генерация отчета\n• make lint - Проверка синтаксиса\n• make cleanup - Очистка данных" 20 70;; \ + "examples") \ + whiptail --title "💡 Примеры использования" \ + --msgbox "Примеры использования:\n\n1. Создание роли nginx:\n make role-create-interactive\n\n2. Создание пресета для 5 хостов:\n make preset-create-interactive\n\n3. Запуск лаборатории с пресетом:\n make lab up PRESET=my-preset\n\n4. Тестирование роли:\n make role test NAME=nginx\n\n5. Генерация HTML отчета:\n make report" 20 70;; \ + "troubleshooting") \ + whiptail --title "🔧 Решение проблем" \ + --msgbox "Решение проблем:\n\n• whiptail не найден:\n make check-whiptail\n\n• Docker не запускается:\n make lab down && make lab up\n\n• Проблемы с vault:\n make vault view\n\n• Очистка всех данных:\n make cleanup\n\n• Проверка синтаксиса:\n make lint\n\n• Просмотр логов:\n make lab logs" 20 70;; \ + "about") \ + whiptail --title "ℹ️ О проекте" \ + --msgbox "Ansible Template v$(VERSION)\n\nУниверсальная лаборатория для тестирования Ansible ролей и playbooks с поддержкой Docker, Kubernetes, и множества готовых пресетов.\n\nАвтор: $(AUTHOR)\nСайт: $(SITE)\nЛицензия: MIT\n\nОсобенности:\n• 🎯 Интерактивный интерфейс\n• 🧪 Универсальная лаборатория\n• ☸️ Kubernetes поддержка\n• 📋 21 готовый пресет\n• 🔐 Безопасность vault\n• 📊 Красивые отчеты" 20 70;; \ + esac + # ============================================================================= # ИНИЦИАЛИЗАЦИЯ И НАСТРОЙКА # ============================================================================= @@ -411,7 +719,7 @@ preset-create-interactive: check-whiptail ## Интерактивное созд echo " family: debian" >> molecule/presets/$$PRESET_NAME.yml; \ elif [ "$$OS_FAMILY" = "redhat" ]; then \ echo " family: redhat" >> molecule/presets/$$PRESET_NAME.yml; \ - else \ + else \ if [ $$((i % 2)) -eq 0 ]; then \ echo " family: debian" >> molecule/presets/$$PRESET_NAME.yml; \ else \ @@ -505,6 +813,51 @@ preset: ## Управление пресетами (list|create|edit|test|copy) # УПРАВЛЕНИЕ РОЛЯМИ # ============================================================================= +.PHONY: playbook-create-interactive +playbook-create-interactive: check-whiptail ## Интерактивное создание playbook + @echo "$(CYAN)🎯 Создание нового Ansible playbook$(RESET)"; \ + PLAYBOOK_NAME=$$(whiptail --inputbox "Введите имя playbook (например: deploy.yml):" 8 50 "deploy.yml" 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ]; then echo "$(RED)❌ Отменено$(RESET)"; exit 1; fi; \ + PLAYBOOK_DESC=$$(whiptail --inputbox "Введите описание playbook:" 8 50 "Развертывание приложения" 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ]; then echo "$(RED)❌ Отменено$(RESET)"; exit 1; fi; \ + PLAYBOOK_HOSTS=$$(whiptail --inputbox "Целевые хосты (по умолчанию: all):" 8 50 "all" 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ]; then echo "$(RED)❌ Отменено$(RESET)"; exit 1; fi; \ + PLAYBOOK_ROLES=$$(whiptail --inputbox "Роли через запятую (например: nginx,apache):" 8 50 "nginx" 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ]; then echo "$(RED)❌ Отменено$(RESET)"; exit 1; fi; \ + PLAYBOOK_TAGS=$$(whiptail --inputbox "Теги через запятую (например: deploy,web):" 8 50 "deploy" 3>&1 1>&2 2>&3); \ + if [ $$? -ne 0 ]; then echo "$(RED)❌ Отменено$(RESET)"; exit 1; fi; \ + echo "$(BLUE)📝 Создание playbook: $$PLAYBOOK_NAME$(RESET)"; \ + mkdir -p files/playbooks; \ + echo "---" > files/playbooks/$$PLAYBOOK_NAME; \ + echo "# Playbook: $$PLAYBOOK_DESC" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo "# Автор: $(AUTHOR)" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo "# Сайт: $(SITE)" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo "" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo "- name: $$PLAYBOOK_DESC" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " hosts: $$PLAYBOOK_HOSTS" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " gather_facts: true" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " tags: [$$PLAYBOOK_TAGS]" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo "" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " pre_tasks:" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " - name: Update system packages" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " package:" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " name: '*'"; \ + echo " state: latest" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " when: ansible_os_family in ['Debian', 'RedHat']" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo "" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " roles:" >> files/playbooks/$$PLAYBOOK_NAME; \ + for role in $$(echo $$PLAYBOOK_ROLES | tr ',' ' '); do \ + echo " - role: $$role" >> files/playbooks/$$PLAYBOOK_NAME; \ + done; \ + echo "" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " post_tasks:" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " - name: Verify deployment" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " debug:" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo " msg: \"Playbook $$PLAYBOOK_NAME completed successfully\"" >> files/playbooks/$$PLAYBOOK_NAME; \ + echo "$(GREEN)✅ Playbook $$PLAYBOOK_NAME создан$(RESET)"; \ + echo "$(BLUE)📁 Файл: files/playbooks/$$PLAYBOOK_NAME$(RESET)"; \ + echo "$(BLUE)📋 Запуск: ansible-playbook files/playbooks/$$PLAYBOOK_NAME$(RESET)" + .PHONY: role-create-interactive role-create-interactive: check-whiptail ## Интерактивное создание роли @echo "$(CYAN)🎯 Создание новой Ansible роли$(RESET)"; \