Files
DevOpsLab/Makefile
Сергей Антропов 696e08aa35 feat: Реорганизация Makefile и добавление Docker образов
- Реорганизован Makefile:
  * Переменные вынесены наверх
  * Справка перенесена в конец
  * Удалены секции molecule и container
  * Объединены presets и preset в одну секцию
  * Переименована секция docker в docker-cmd

- Добавлены Docker образы:
  * ansible-controller - основной контроллер
  * alt-linux, astra-linux, redos - российские дистрибутивы
  * rhel, centos, alma, rocky - RHEL-совместимые образы

- Обновлены preset'ы:
  * Добавлены описания #description: во все preset'ы
  * Переименован docker.yml в docker-test.yml
  * Добавлены новые preset'ы: etcd-patroni, multi-os

- Добавлена документация:
  * docs/examples.md - примеры использования
  * docs/universal-testing.md - универсальное тестирование
  * dockerfiles/README.md - описание Docker образов

- Улучшена функциональность:
  * Единообразный стиль команд make [категория] [действие]
  * Улучшенный вывод информации о preset'ах
  * Добавлены пустые цели для совместимости
2025-10-25 11:29:37 +03:00

445 lines
20 KiB
Makefile
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# =============================================================================
# AnsibleTemplate - Универсальная система тестирования Ansible ролей
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
# =============================================================================
SHELL := /bin/bash
# =============================================================================
# ПЕРЕМЕННЫЕ
# =============================================================================
# Цвета для вывода
RED := \033[0;31m
GREEN := \033[0;32m
YELLOW := \033[0;33m
BLUE := \033[0;34m
PURPLE := \033[0;35m
CYAN := \033[0;36m
WHITE := \033[0;37m
RESET := \033[0m
# Глобальные переменные
PROJECT_NAME ?= ansible-template
VERSION ?= 0.1.0
AUTHOR ?= "Сергей Антропов"
SITE ?= "https://devops.org.ru"
DOCKER_IMAGE ?= inecs/ansible-controller:latest
DOCKER_DIND_IMAGE ?= docker:27-dind
CONTAINER_NAME ?= ansible-controller
# Переменные для Docker Hub
DOCKER_REGISTRY ?= inecs
DOCKER_VERSION ?= latest
DOCKER_IMAGES := ansible-controller alt-linux astra-linux redos rhel centos alma rocky
.PHONY: role vault git docker-cmd presets controller help
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С РОЛЯМИ
# =============================================================================
role:
@case "$(word 2, $(MAKECMDGOALS))" in \
lint) \
echo "🔍 Проверка синтаксиса ролей ..."; \
docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace -e ANSIBLE_FORCE_COLOR=1 $(DOCKER_IMAGE) bash -c "ansible-lint roles/ --config-file .ansible-lint || true"; \
echo "✅ Lint завершен";; \
test) \
echo "🚀 Тестирование ролей ..."; \
PRESET="default"; \
ARGS="$(wordlist 3,10,$(MAKECMDGOALS))"; \
if [ -n "$$ARGS" ]; then \
PRESET="$$(echo $$ARGS | cut -d' ' -f1)"; \
fi; \
echo "📋 Используется пресет: $$PRESET"; \
if [ ! -f "molecule/presets/$$PRESET.yml" ]; then \
echo "❌ Ошибка: Пресет '$$PRESET' не найден!"; \
echo "💡 Доступные пресеты:"; \
ls -1 molecule/presets/*.yml 2>/dev/null | sed 's|molecule/presets/||g' | sed 's|\.yml||g' | sed 's/^/ - /' || echo " ⚠️ Пресеты не найдены"; \
exit 1; \
fi; \
echo ""; \
if [ "$$PRESET" = "standart" ]; then \
./scripts/test-standart.sh; \
else \
docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \
-v /var/run/docker.sock:/var/run/docker.sock \
-e ANSIBLE_FORCE_COLOR=1 \
-e MOLECULE_PRESET=$$PRESET \
$(DOCKER_IMAGE) \
bash -c "cd molecule/default && ansible-playbook -i localhost, create.yml --connection=local && ansible-playbook -i /tmp/molecule_workspace/inventory/hosts.ini site.yml && ansible-playbook -i localhost, destroy.yml --connection=local" || echo "✅ Тестирование завершено"; \
fi;; \
deploy) \
echo "🚀 Развертывание ролей на реальные серверы..."; \
echo ""; \
if [ ! -f "inventory/hosts.ini" ]; then \
echo "❌ Ошибка: Файл inventory/hosts.ini не найден!"; \
echo "💡 Создайте файл inventory/hosts.ini с вашими серверами"; \
exit 1; \
fi; \
echo "📋 Используется inventory: inventory/hosts.ini"; \
echo "📄 Содержимое inventory:"; \
cat inventory/hosts.ini; \
echo ""; \
echo "🚀 Запуск развертывания..."; \
ansible-playbook -i inventory/hosts.ini deploy.yml --check; \
echo ""; \
read -p "Продолжить развертывание? (y/N): " confirm; \
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
ansible-playbook -i inventory/hosts.ini deploy.yml; \
else \
echo "❌ Развертывание отменено"; \
fi;; \
*) \
echo "🎯 Доступные команды:"; \
echo " make role test [preset] - протестировать роли"; \
echo " make role deploy - развернуть роли"; \
echo " make role lint - проверить синтаксис";; \
esac
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С PRESET'АМИ
# =============================================================================
presets:
@case "$(word 2, $(MAKECMDGOALS))" in \
list) \
echo "📋 Доступные пресеты:"; \
echo ""; \
preset_count=0; \
for preset in molecule/presets/*.yml; do \
if [ -f "$$preset" ]; then \
preset_name=$$(basename "$$preset" .yml); \
preset_desc=$$(grep -E "^#description:" "$$preset" | head -1 | sed 's/^#description: *//' || echo "Описание отсутствует"); \
host_count=$$(grep -c "^- name:" "$$preset" 2>/dev/null || echo "?"); \
printf " 📄 %s - %s (%s хостов)\n" "$$preset_name" "$$preset_desc" "$$host_count"; \
preset_count=$$((preset_count + 1)); \
fi; \
done; \
if [ $$preset_count -eq 0 ]; then \
echo " ⚠️ Пресеты не найдены"; \
fi;; \
info) \
if [ -z "$(PRESET)" ]; then \
echo "❌ Ошибка: Укажите PRESET=имя_пресета"; \
echo "💡 Пример: make presets info PRESET=etcd-patroni"; \
exit 1; \
fi; \
if [ ! -f "molecule/presets/$(PRESET).yml" ]; then \
echo "❌ Ошибка: Пресет '$(PRESET)' не найден!"; \
echo "💡 Доступные пресеты:"; \
make presets list; \
exit 1; \
fi; \
echo "📋 Информация о пресете: $(PRESET)"; \
echo ""; \
echo "📄 Описание:"; \
grep -E "^#description:" "molecule/presets/$(PRESET).yml" | head -1 | sed 's/^#description: *//' || echo "Описание отсутствует"; \
echo ""; \
echo "🏠 Хосты:"; \
grep -E "^- name:" "molecule/presets/$(PRESET).yml" | sed 's/^- name: / - /' || echo "Хосты не найдены"; \
echo ""; \
echo "🌐 Сеть:"; \
grep -E "^docker_network:" "molecule/presets/$(PRESET).yml" | sed 's/^docker_network: / - /' || echo "Сеть не указана"; \
echo ""; \
echo "🐳 Образы:"; \
grep -E "^- " "molecule/presets/$(PRESET).yml" | grep -E "family:" | sed 's/.*family: / - /' || echo "Образы не найдены";; \
test) \
if [ -z "$(PRESET)" ]; then \
echo "❌ Ошибка: Укажите PRESET=имя_пресета"; \
echo "💡 Пример: make presets test PRESET=etcd-patroni"; \
exit 1; \
fi; \
if [ ! -f "molecule/presets/$(PRESET).yml" ]; then \
echo "❌ Ошибка: Пресет '$(PRESET)' не найден!"; \
echo "💡 Доступные пресеты:"; \
make presets list; \
exit 1; \
fi; \
echo "🚀 Тестирование с пресетом: $(PRESET)"; \
echo ""; \
docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \
-v /var/run/docker.sock:/var/run/docker.sock \
-e ANSIBLE_FORCE_COLOR=1 \
-e MOLECULE_PRESET=$(PRESET) \
$(DOCKER_IMAGE) \
bash -c "cd molecule/default && molecule test" || echo "✅ Тестирование завершено";; \
*) \
echo "🎯 Доступные команды:"; \
echo ""; \
echo " 📋 make presets list - показать список preset'ов"; \
echo " 📄 make presets info - информация о preset'е"; \
echo " 🚀 make presets test - тест с preset'ом"; \
echo ""; \
echo "💡 Примеры:"; \
echo " make presets list"; \
echo " make presets info PRESET=etcd-patroni"; \
echo " make presets test PRESET=etcd-patroni";; \
esac
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С VAULT
# =============================================================================
vault:
@case "$(word 2, $(MAKECMDGOALS))" in \
create) \
echo "🔐 Создание файла секретов..."; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault create --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \
edit) \
echo "🔐 Редактирование секретов..."; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault edit --vault-password-file vault/.vault vault/$$FILE.yml;; \
show) \
echo "🔐 Просмотр секретов..."; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault view --vault-password-file vault/.vault vault/$$FILE.yml;; \
delete) \
echo "🔐 Удаление секретов..."; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
rm -f vault/$$FILE.yml;; \
encrypt) \
echo "🔐 Шифрование файла..."; \
ls -la vault/*.yml 2>/dev/null || echo "Нет файлов для шифрования"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault encrypt --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \
decrypt) \
echo "🔐 Расшифровка файла..."; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault decrypt --vault-password-file vault/.vault vault/$$FILE.yml;; \
rekey) \
echo "🔐 Смена пароля..."; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault rekey --vault-password-file vault/.vault vault/$$FILE.yml;; \
check) \
echo "🔍 Проверка vault файлов..."; \
if [ ! -d "vault" ]; then \
echo "❌ Директория vault не найдена"; \
exit 1; \
fi; \
vault_files=$$(find vault -name "*.yml" -type f 2>/dev/null); \
if [ -z "$$vault_files" ]; then \
echo "⚠️ Vault файлы не найдены"; \
exit 0; \
fi; \
echo "📋 Найденные vault файлы:"; \
for file in $$vault_files; do \
echo " 📄 $$file"; \
done; \
echo ""; \
echo "🔍 Проверка структуры..."; \
for file in $$vault_files; do \
if grep -q "ANSIBLE_VAULT" "$$file"; then \
echo "$$file - зашифрован"; \
else \
echo " ⚠️ $$file - не зашифрован"; \
fi; \
done;; \
scan) \
echo "🔍 Поиск секретов в проекте..."; \
echo "📋 Поиск потенциальных секретов:"; \
find . -name "*.yml" -o -name "*.yaml" | grep -v ".git" | while read file; do \
if grep -qE "(password|secret|key|token|api_key)" "$$file" 2>/dev/null; then \
echo " ⚠️ $$file - содержит потенциальные секреты"; \
fi; \
done; \
echo ""; \
echo "💡 Рекомендации:"; \
echo " - Используйте ansible-vault для шифрования секретов"; \
echo " - Не храните секреты в открытом виде"; \
echo " - Регулярно проверяйте файлы на наличие секретов";; \
*) \
echo "🎯 Доступные команды:"; \
echo " make vault create - создать файл секретов"; \
echo " make vault edit - редактировать секреты"; \
echo " make vault show - показать секреты"; \
echo " make vault delete - удалить секреты"; \
echo " make vault encrypt - зашифровать файл"; \
echo " make vault decrypt - расшифровать файл"; \
echo " make vault rekey - сменить пароль"; \
echo " make vault check - проверка vault файлов"; \
echo " make vault scan - поиск секретов";; \
esac
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С GIT
# =============================================================================
git:
@case "$(word 2, $(MAKECMDGOALS))" in \
push) \
echo "📤 Отправка изменений в репозиторий..."; \
git add .; \
git commit -m "Обновление проекта"; \
git push origin main;; \
pull) \
echo "📥 Получение изменений из репозитория..."; \
git pull origin main;; \
new) \
echo "🌿 Создание новой ветки..."; \
read -p "Введите имя ветки: " BRANCH; \
git checkout -b "$$BRANCH"; \
echo "✅ Ветка '$$BRANCH' создана";; \
*) \
echo "🎯 Доступные команды:"; \
echo " make git push - запушить изменения"; \
echo " make git pull - получить изменения"; \
echo " make git new - создать новую ветку";; \
esac
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С DOCKER
# =============================================================================
docker-cmd:
@case "$(word 2, $(MAKECMDGOALS))" in \
prepare) \
echo "🔧 Подготовка Docker образов для Docker Hub..."; \
echo "📋 Registry: $(DOCKER_REGISTRY)"; \
echo "📋 Version: $(DOCKER_VERSION)"; \
echo "📋 Images: $(DOCKER_IMAGES)"; \
echo ""; \
echo "💡 Для работы с Docker Hub выполните:"; \
echo " docker login - авторизация в Docker Hub"; \
echo " make docker build - сборка образов"; \
echo " make docker push - отправка в Docker Hub";; \
build) \
echo "🐳 Сборка Docker образов..."; \
for image in $(DOCKER_IMAGES); do \
echo "🔨 Сборка $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \
cd dockerfiles/$$image && docker build -t $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION) .; \
done; \
echo "✅ Образы собраны";; \
push) \
echo "📤 Отправка Docker образов в Docker Hub..."; \
for image in $(DOCKER_IMAGES); do \
echo "📤 Отправка $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \
docker push $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION); \
done; \
echo "✅ Образы отправлены в Docker Hub";; \
pull) \
echo "📥 Загрузка Docker образов из Docker Hub..."; \
for image in $(DOCKER_IMAGES); do \
echo "📥 Загрузка $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \
docker pull $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION) || echo "⚠️ Образ $$image не найден в Docker Hub"; \
done; \
echo "✅ Загрузка завершена";; \
clean) \
echo "🧹 Очистка Docker образов..."; \
for image in $(DOCKER_IMAGES); do \
echo "🗑️ Удаление $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \
docker rmi $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION) 2>/dev/null || true; \
done; \
echo "✅ Образы очищены";; \
info) \
echo "📊 Информация об образах..."; \
for image in $(DOCKER_IMAGES); do \
if docker images | grep -q "$(DOCKER_REGISTRY)/$$image"; then \
echo "📦 $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \
docker images | grep "$(DOCKER_REGISTRY)/$$image" | head -1; \
fi; \
done;; \
update) \
echo "🔄 Обновление всех образов..."; \
$(MAKE) docker pull; \
$(MAKE) docker build; \
$(MAKE) docker push; \
echo "✅ Все образы обновлены";; \
*) \
echo "🎯 Доступные команды:"; \
echo ""; \
echo " 🔧 make docker prepare - подготовка к работе с Docker Hub"; \
echo " 🐳 make docker build - собрать все образы"; \
echo " 📤 make docker push - отправить образы в Docker Hub"; \
echo " 📥 make docker pull - загрузить образы из Docker Hub"; \
echo " 🧹 make docker clean - удалить образы"; \
echo " 📊 make docker info - информация об образах"; \
echo " 🔄 make docker update - обновить все образы (pull + build + push)";; \
esac
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С ANSIBLE-CONTROLLER
# =============================================================================
controller:
@case "$(word 2, $(MAKECMDGOALS))" in \
build) \
echo "🔨 Сборка ansible-controller..."; \
cd dockerfiles/ansible-controller && docker build -t $(DOCKER_REGISTRY)/ansible-controller:$(DOCKER_VERSION) .; \
echo "✅ ansible-controller собран";; \
run) \
echo "🚀 Запуск ansible-controller..."; \
cd dockerfiles/ansible-controller && docker-compose up -d; \
echo "✅ ansible-controller запущен";; \
stop) \
echo "🛑 Остановка ansible-controller..."; \
cd dockerfiles/ansible-controller && docker-compose down; \
echo "✅ ansible-controller остановлен";; \
*) \
echo "🎯 Доступные команды:"; \
echo ""; \
echo " 🔨 make controller build - собрать ansible-controller"; \
echo " 🚀 make controller run - запустить ansible-controller"; \
echo " 🛑 make controller stop - остановить ansible-controller";; \
esac
# =============================================================================
# СПРАВКА
# =============================================================================
help:
@echo "=========================================="
@echo "AnsibleTemplate - Универсальная система"
@echo "тестирования Ansible ролей"
@echo "=========================================="
@echo ""
@echo "📁 Структура проекта:"
@echo " scripts/ - Скрипты автоматизации"
@echo " inventory/ - Инвентори файлы"
@echo " molecule/default/ - Molecule конфигурация"
@echo " roles/ - Ansible роли"
@echo " vault/ - Зашифрованные секреты"
@echo ""
@echo "🚀 ОСНОВНЫЕ КОМАНДЫ:"
@echo " make role test [preset] - протестировать роли"
@echo " make role deploy - развернуть роли"
@echo " make role lint - проверить синтаксис"
@echo ""
@echo "📋 PRESET'Ы:"
@echo " make presets list - показать все preset'ы"
@echo " make presets test - тест с preset'ом"
@echo ""
@echo "🐳 DOCKER:"
@echo " make docker-cmd build - собрать образы"
@echo " make docker-cmd push - отправить в Docker Hub"
@echo " make docker-cmd info - информация об образах"
@echo ""
@echo "🔐 VAULT:"
@echo " make vault create - создать файл секретов"
@echo " make vault check - проверка vault файлов"
@echo ""
@echo "📖 Подробная справка: make [команда]"
@echo "=========================================="
# Пустые цели для совместимости
view create edit show delete lint deploy new advanced list info test build push pull clean prepare update run stop:
@true