Initial commit: Message Gateway project

- FastAPI приложение для отправки мониторинговых алертов в мессенджеры
- Поддержка Telegram и MAX/VK
- Интеграция с Grafana, Zabbix, AlertManager
- Автоматическое создание тикетов в Jira
- Управление группами мессенджеров через API
- Декораторы для авторизации и скрытия эндпоинтов
- Подробная документация в папке docs/

Автор: Сергей Антропов
Сайт: https://devops.org.ru
This commit is contained in:
2025-11-12 20:25:11 +03:00
commit b90def35ed
72 changed files with 10609 additions and 0 deletions

534
Makefile Normal file
View File

@@ -0,0 +1,534 @@
# Makefile для Message Gateway
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
.PHONY: help build up up-build down restart logs shell test clean clean-all lint format install dev stop status health ready version psql redis-cli
.PHONY: docker docker-build docker-tag docker-push docker-run docker-stop docker-logs docker-shell
.PHONY: env env-check env-create env-create-force
.PHONY: git git-status git-pull git-push git-commit git-add git-branch
.PHONY: k8s k8s-apply k8s-delete k8s-status k8s-logs k8s-shell k8s-contexts k8s-set-context
# Цвета для вывода
COLOR_RESET := \033[0m
COLOR_BOLD := \033[1m
COLOR_RED := \033[31m
COLOR_GREEN := \033[32m
COLOR_YELLOW := \033[33m
COLOR_BLUE := \033[34m
COLOR_MAGENTA := \033[35m
COLOR_CYAN := \033[36m
# Переменные
DOCKER_COMPOSE := docker compose
DOCKER := docker
PYTHON := python3
APP_NAME := message-gateway
IMAGE_NAME := message-gateway
REGISTRY := hub.cism-ms.ru/library
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "v0.1.0")
TAG := $(VERSION)
KUBECTL := kubectl
K8S_CONTEXT := $(shell $(KUBECTL) config current-context 2>/dev/null || echo "")
K8S_NAMESPACE := message-gateway
K8S_MANIFEST := kubernetes.yaml
GIT := git
# Проверка наличия .env файла
ENV_FILE := .env
ifeq ($(wildcard $(ENV_FILE)),)
$(warning $(COLOR_YELLOW)Файл .env не найден. Создайте его на основе env.example$(COLOR_RESET))
endif
# ============================================================================
# Помощь
# ============================================================================
help: ## 📖 Показать справку по командам
@echo "$(COLOR_BOLD)$(COLOR_CYAN)Message Gateway - Доступные команды:$(COLOR_RESET)"
@echo ""
@echo "$(COLOR_BOLD)$(COLOR_YELLOW)Основные команды:$(COLOR_RESET)"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | grep -v "^[[:space:]]*#" | awk 'BEGIN {FS = ":.*?## "}; {if ($$1 ~ /^(build|up-build|up|down|restart|logs|shell|stop|status|health|ready)$$/) printf " $(COLOR_GREEN)%-25s$(COLOR_RESET) %s\n", $$1, $$2}'
@echo ""
@echo "$(COLOR_BOLD)$(COLOR_YELLOW)Разработка:$(COLOR_RESET)"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | grep -v "^[[:space:]]*#" | awk 'BEGIN {FS = ":.*?## "}; {if ($$1 ~ /^(dev|test|lint|format|install|clean|clean-all)$$/) printf " $(COLOR_GREEN)%-25s$(COLOR_RESET) %s\n", $$1, $$2}'
@echo ""
@echo "$(COLOR_BOLD)$(COLOR_YELLOW)Docker команды:$(COLOR_RESET)"
@echo " $(COLOR_GREEN)make docker build$(COLOR_RESET) 🐳 Собрать Docker образ"
@echo " $(COLOR_GREEN)make docker tag$(COLOR_RESET) 🏷️ Тегировать Docker образ"
@echo " $(COLOR_GREEN)make docker push$(COLOR_RESET) 📤 Отправить образ в registry"
@echo " $(COLOR_GREEN)make docker run$(COLOR_RESET) 🏃 Запустить контейнер"
@echo " $(COLOR_GREEN)make docker stop$(COLOR_RESET) 🛑 Остановить контейнер"
@echo " $(COLOR_GREEN)make docker logs$(COLOR_RESET) 📋 Показать логи контейнера"
@echo " $(COLOR_GREEN)make docker shell$(COLOR_RESET) 🐚 Открыть shell в контейнере"
@echo " $(COLOR_YELLOW)Использование: make docker CMD=build$(COLOR_RESET)"
@echo ""
@echo "$(COLOR_BOLD)$(COLOR_YELLOW)Git команды:$(COLOR_RESET)"
@echo " $(COLOR_GREEN)make git status$(COLOR_RESET) 📊 Показать статус репозитория"
@echo " $(COLOR_GREEN)make git pull$(COLOR_RESET) ⬇️ Получить изменения из удаленного репозитория"
@echo " $(COLOR_GREEN)make git push$(COLOR_RESET) ⬆️ Отправить изменения в удаленный репозиторий"
@echo " $(COLOR_GREEN)make git add [file]$(COLOR_RESET) Добавить файлы в индекс"
@echo " $(COLOR_GREEN)make git commit [msg]$(COLOR_RESET) 💾 Создать коммит"
@echo " $(COLOR_GREEN)make git branch$(COLOR_RESET) 🌿 Показать список веток"
@echo " $(COLOR_YELLOW)Использование: make git CMD=push ARGS=origin main$(COLOR_RESET)"
@echo ""
@echo "$(COLOR_BOLD)$(COLOR_YELLOW)Kubernetes команды:$(COLOR_RESET)"
@echo " $(COLOR_GREEN)make k8s contexts$(COLOR_RESET) 📋 Показать доступные контексты"
@echo " $(COLOR_GREEN)make k8s set-context [name]$(COLOR_RESET) 🔄 Установить контекст"
@echo " $(COLOR_GREEN)make k8s apply$(COLOR_RESET) ✅ Применить манифесты"
@echo " $(COLOR_GREEN)make k8s delete$(COLOR_RESET) 🗑️ Удалить ресурсы"
@echo " $(COLOR_GREEN)make k8s status$(COLOR_RESET) 📊 Показать статус подов"
@echo " $(COLOR_GREEN)make k8s logs$(COLOR_RESET) 📋 Показать логи подов"
@echo " $(COLOR_GREEN)make k8s shell$(COLOR_RESET) 🐚 Открыть shell в поде"
@echo " $(COLOR_YELLOW)Использование: make k8s CMD=apply CONTEXT=<контекст>$(COLOR_RESET)"
@if [ -n "$(K8S_CONTEXT)" ]; then \
echo " $(COLOR_CYAN)Текущий контекст: $(COLOR_BOLD)$(K8S_CONTEXT)$(COLOR_RESET)"; \
fi
@echo ""
@echo "$(COLOR_BOLD)$(COLOR_YELLOW)Env команды:$(COLOR_RESET)"
@echo " $(COLOR_GREEN)make env check$(COLOR_RESET) 🔍 Проверить наличие .env файла"
@echo " $(COLOR_GREEN)make env create$(COLOR_RESET) 📝 Создать .env файл из env.example"
@echo " $(COLOR_GREEN)make env create-force$(COLOR_RESET) 📝 Принудительно создать .env файл"
@echo " $(COLOR_YELLOW)Использование: make env CMD=check$(COLOR_RESET)"
@echo ""
@echo "$(COLOR_BOLD)$(COLOR_YELLOW)Утилиты:$(COLOR_RESET)"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | grep -v "^[[:space:]]*#" | awk 'BEGIN {FS = ":.*?## "}; {if ($$1 ~ /^(version|psql|redis-cli)$$/) printf " $(COLOR_GREEN)%-25s$(COLOR_RESET) %s\n", $$1, $$2}'
@echo ""
# ============================================================================
# Основные команды
# ============================================================================
build: ## 🔨 Собрать Docker образ
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Сборка Docker образа...$(COLOR_RESET)"
@$(DOCKER_COMPOSE) build --no-cache
@echo "$(COLOR_GREEN)✓ Образ собран успешно$(COLOR_RESET)"
up: ## 🚀 Запустить приложение
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Запуск приложения...$(COLOR_RESET)"
@$(DOCKER_COMPOSE) up -d
@echo "$(COLOR_GREEN)✓ Приложение запущено$(COLOR_RESET)"
@echo "$(COLOR_CYAN)Для просмотра логов: $(COLOR_BOLD)make logs$(COLOR_RESET)"
up-build: build up ## 🔨 Собрать и запустить приложение
@echo "$(COLOR_GREEN)✓ Приложение собрано и запущено$(COLOR_RESET)"
down: ## 🛑 Остановить приложение
@echo "$(COLOR_BOLD)$(COLOR_YELLOW)Остановка приложения...$(COLOR_RESET)"
@$(DOCKER_COMPOSE) down
@echo "$(COLOR_GREEN)✓ Приложение остановлено$(COLOR_RESET)"
restart: ## 🔄 Перезапустить приложение
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Перезапуск приложения...$(COLOR_RESET)"
@$(DOCKER_COMPOSE) restart
@echo "$(COLOR_GREEN)✓ Приложение перезапущено$(COLOR_RESET)"
logs: ## 📋 Показать логи приложения
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Просмотр логов приложения...$(COLOR_RESET)"
@clear || true
@$(DOCKER_COMPOSE) logs -f --tail=50 $(APP_NAME)
shell: ## 🐚 Открыть shell в контейнере
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Открытие shell в контейнере...$(COLOR_RESET)"
@clear || true
@$(DOCKER_COMPOSE) exec $(APP_NAME) /bin/bash
stop: ## ⏹️ Остановить приложение (alias для down)
@$(MAKE) down
status: ## 📊 Показать статус контейнеров
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Статус контейнеров:$(COLOR_RESET)"
@$(DOCKER_COMPOSE) ps
health: ## ❤️ Проверить здоровье приложения
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Проверка здоровья приложения...$(COLOR_RESET)"
@curl -f http://localhost:8000/api/v1/health || (echo "$(COLOR_RED)✗ Приложение не отвечает$(COLOR_RESET)" && exit 1)
@echo "$(COLOR_GREEN)✓ Приложение здорово$(COLOR_RESET)"
ready: ## ✅ Проверить готовность приложения
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Проверка готовности приложения...$(COLOR_RESET)"
@curl -f http://localhost:8000/api/v1/health/ready || (echo "$(COLOR_RED)✗ Приложение не готово$(COLOR_RESET)" && exit 1)
@echo "$(COLOR_GREEN)✓ Приложение готово$(COLOR_RESET)"
# ============================================================================
# Разработка
# ============================================================================
dev: ## 🔧 Запустить в режиме разработки
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Запуск в режиме разработки...$(COLOR_RESET)"
@$(DOCKER_COMPOSE) up --build
test: ## 🧪 Запустить тесты
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Запуск тестов...$(COLOR_RESET)"
@if [ -f docker-compose.test.yaml ]; then \
$(DOCKER_COMPOSE) -f docker-compose.test.yaml up --abort-on-container-exit; \
else \
echo "$(COLOR_YELLOW)⚠ Файл docker-compose.test.yaml не найден$(COLOR_RESET)"; \
echo "$(COLOR_CYAN)Запуск тестов через pytest...$(COLOR_RESET)"; \
$(DOCKER_COMPOSE) exec $(APP_NAME) pytest -v || true; \
fi
lint: ## 🔍 Запустить линтер
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Запуск линтера...$(COLOR_RESET)"
@$(DOCKER_COMPOSE) exec $(APP_NAME) python -m pylint app/ || echo "$(COLOR_YELLOW)⚠ Линтер не установлен или найдены ошибки$(COLOR_RESET)"
format: ## 🎨 Форматировать код
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Форматирование кода...$(COLOR_RESET)"
@$(DOCKER_COMPOSE) exec $(APP_NAME) python -m black app/ || echo "$(COLOR_YELLOW)⚠ Black не установлен$(COLOR_RESET)"
install: ## 📦 Установить зависимости
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Установка зависимостей...$(COLOR_RESET)"
@pip install -r requirements.txt || $(PYTHON) -m pip install -r requirements.txt
@echo "$(COLOR_GREEN)✓ Зависимости установлены$(COLOR_RESET)"
clean: ## 🧹 Очистить Docker образы и контейнеры
@echo "$(COLOR_BOLD)$(COLOR_YELLOW)Очистка Docker ресурсов...$(COLOR_RESET)"
@$(DOCKER_COMPOSE) down -v
@$(DOCKER) system prune -f
@echo "$(COLOR_GREEN)✓ Очистка завершена$(COLOR_RESET)"
clean-all: ## 🗑️ Очистить все Docker ресурсы (включая volumes)
@echo "$(COLOR_BOLD)$(COLOR_RED)Очистка всех Docker ресурсов...$(COLOR_RESET)"
@$(DOCKER_COMPOSE) down -v --rmi all
@$(DOCKER) system prune -af --volumes
@echo "$(COLOR_GREEN)✓ Полная очистка завершена$(COLOR_RESET)"
# ============================================================================
# Docker команды (подкоманды через make docker CMD=<cmd>)
# ============================================================================
docker: ## 🐳 Docker команды (используйте: make docker CMD=build|tag|push|run|stop|logs|shell)
@if [ -z "$(CMD)" ]; then \
echo "$(COLOR_BOLD)$(COLOR_CYAN)Docker команды:$(COLOR_RESET)"; \
echo ""; \
echo " $(COLOR_GREEN)make docker build$(COLOR_RESET) - Собрать Docker образ"; \
echo " $(COLOR_GREEN)make docker tag$(COLOR_RESET) - Тегировать Docker образ"; \
echo " $(COLOR_GREEN)make docker push$(COLOR_RESET) - Отправить образ в registry"; \
echo " $(COLOR_GREEN)make docker run$(COLOR_RESET) - Запустить контейнер"; \
echo " $(COLOR_GREEN)make docker stop$(COLOR_RESET) - Остановить контейнер"; \
echo " $(COLOR_GREEN)make docker logs$(COLOR_RESET) - Показать логи контейнера"; \
echo " $(COLOR_GREEN)make docker shell$(COLOR_RESET) - Открыть shell в контейнере"; \
echo ""; \
echo "$(COLOR_YELLOW)Использование:$(COLOR_RESET)"; \
echo " $(COLOR_CYAN)make docker CMD=build$(COLOR_RESET)"; \
echo " $(COLOR_CYAN)make docker-build$(COLOR_RESET) (прямой вызов)"; \
else \
$(MAKE) docker-$(CMD); \
fi
docker-build: ## 🐳 Собрать Docker образ
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Сборка Docker образа...$(COLOR_RESET)"
@$(DOCKER) build --no-cache -t $(IMAGE_NAME):$(TAG) .
@echo "$(COLOR_GREEN)✓ Образ собран: $(IMAGE_NAME):$(TAG)$(COLOR_RESET)"
docker-tag: docker-build ## 🏷️ Тегировать Docker образ для registry
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Тегирование образа...$(COLOR_RESET)"
@$(DOCKER) tag $(IMAGE_NAME):$(TAG) $(REGISTRY)/$(IMAGE_NAME):$(TAG) || \
(echo "$(COLOR_RED)✗ Ошибка тегирования образа$(COLOR_RESET)" && exit 1)
@echo "$(COLOR_GREEN)✓ Образ помечен: $(REGISTRY)/$(IMAGE_NAME):$(TAG)$(COLOR_RESET)"
docker-push: docker-tag ## 📤 Собрать, тегировать и отправить образ в registry
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Отправка образа в registry...$(COLOR_RESET)"
@$(DOCKER) push $(REGISTRY)/$(IMAGE_NAME):$(TAG) || \
(echo "$(COLOR_RED)✗ Ошибка отправки образа в registry$(COLOR_RESET)" && exit 1)
@echo "$(COLOR_GREEN)✓ Образ отправлен: $(REGISTRY)/$(IMAGE_NAME):$(TAG)$(COLOR_RESET)"
docker-run: docker-build ## 🏃 Запустить контейнер
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Запуск контейнера...$(COLOR_RESET)"
@if [ ! -f $(ENV_FILE) ]; then \
echo "$(COLOR_RED)✗ Файл .env не найден$(COLOR_RESET)"; \
echo "$(COLOR_YELLOW)Создайте файл .env на основе env.example$(COLOR_RESET)"; \
exit 1; \
fi
@$(DOCKER) run -d \
--name $(APP_NAME) \
-p 8000:8000 \
--env-file $(ENV_FILE) \
-v $$(pwd)/app:/app/app \
-v $$(pwd)/config:/app/config \
-v $$(pwd)/templates:/app/templates \
$(IMAGE_NAME):$(TAG) || \
(echo "$(COLOR_RED)✗ Ошибка запуска контейнера$(COLOR_RESET)" && exit 1)
@echo "$(COLOR_GREEN)✓ Контейнер запущен$(COLOR_RESET)"
docker-stop: ## 🛑 Остановить контейнер
@echo "$(COLOR_BOLD)$(COLOR_YELLOW)Остановка контейнера...$(COLOR_RESET)"
@$(DOCKER) stop $(APP_NAME) || echo "$(COLOR_YELLOW)⚠ Контейнер не запущен$(COLOR_RESET)"
@$(DOCKER) rm $(APP_NAME) || echo "$(COLOR_YELLOW)⚠ Контейнер не существует$(COLOR_RESET)"
@echo "$(COLOR_GREEN)✓ Контейнер остановлен$(COLOR_RESET)"
docker-logs: ## 📋 Показать логи контейнера
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Просмотр логов контейнера...$(COLOR_RESET)"
@clear || true
@$(DOCKER) logs -f --tail=50 $(APP_NAME)
docker-shell: ## 🐚 Открыть shell в контейнере
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Открытие shell в контейнере...$(COLOR_RESET)"
@clear || true
@$(DOCKER) exec -it $(APP_NAME) /bin/bash
# ============================================================================
# Git команды (подкоманды через make git CMD=<cmd>)
# ============================================================================
git: ## 📦 Git команды (используйте: make git CMD=status|pull|push|add|commit|branch)
@if [ -z "$(CMD)" ]; then \
echo "$(COLOR_BOLD)$(COLOR_CYAN)Git команды:$(COLOR_RESET)"; \
echo ""; \
echo " $(COLOR_GREEN)make git status$(COLOR_RESET) - Показать статус репозитория"; \
echo " $(COLOR_GREEN)make git pull$(COLOR_RESET) - Получить изменения"; \
echo " $(COLOR_GREEN)make git push$(COLOR_RESET) - Отправить изменения"; \
echo " $(COLOR_GREEN)make git add [file]$(COLOR_RESET) - Добавить файлы"; \
echo " $(COLOR_GREEN)make git commit [msg]$(COLOR_RESET) - Создать коммит"; \
echo " $(COLOR_GREEN)make git branch$(COLOR_RESET) - Показать список веток"; \
echo ""; \
echo "$(COLOR_YELLOW)Использование:$(COLOR_RESET)"; \
echo " $(COLOR_CYAN)make git CMD=status$(COLOR_RESET)"; \
echo " $(COLOR_CYAN)make git CMD=push ARGS=origin main$(COLOR_RESET)"; \
echo " $(COLOR_CYAN)make git-status$(COLOR_RESET) (прямой вызов)"; \
else \
$(MAKE) git-$(CMD) ARGS="$(ARGS)"; \
fi
git-status: ## 📊 Показать статус репозитория
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Статус репозитория:$(COLOR_RESET)"
@$(GIT) status
git-pull: ## ⬇️ Получить изменения из удаленного репозитория
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Получение изменений из удаленного репозитория...$(COLOR_RESET)"
@if [ -z "$(ARGS)" ]; then \
$(GIT) pull || (echo "$(COLOR_RED)✗ Ошибка получения изменений$(COLOR_RESET)" && exit 1); \
else \
$(GIT) pull $(ARGS) || (echo "$(COLOR_RED)✗ Ошибка получения изменений$(COLOR_RESET)" && exit 1); \
fi
@echo "$(COLOR_GREEN)✓ Изменения получены$(COLOR_RESET)"
git-push: ## ⬆️ Отправить изменения в удаленный репозиторий
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Отправка изменений в удаленный репозиторий...$(COLOR_RESET)"
@if [ -z "$(ARGS)" ]; then \
$(GIT) push || (echo "$(COLOR_RED)✗ Ошибка отправки изменений$(COLOR_RESET)" && exit 1); \
else \
$(GIT) push $(ARGS) || (echo "$(COLOR_RED)✗ Ошибка отправки изменений$(COLOR_RESET)" && exit 1); \
fi
@echo "$(COLOR_GREEN)✓ Изменения отправлены$(COLOR_RESET)"
git-add: ## Добавить файлы в индекс
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Добавление файлов в индекс...$(COLOR_RESET)"
@if [ -z "$(ARGS)" ]; then \
echo "$(COLOR_YELLOW)⚠ Укажите файлы для добавления: make git add ARGS=<файлы>$(COLOR_RESET)"; \
echo "$(COLOR_YELLOW)Или используйте: make git-add ARGS=<файлы>$(COLOR_RESET)"; \
exit 1; \
fi
@$(GIT) add $(ARGS)
@echo "$(COLOR_GREEN)✓ Файлы добавлены в индекс$(COLOR_RESET)"
git-commit: ## 💾 Создать коммит
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Создание коммита...$(COLOR_RESET)"
@if [ -z "$(ARGS)" ]; then \
echo "$(COLOR_YELLOW)⚠ Укажите сообщение коммита: make git commit ARGS=\"<сообщение>\"$(COLOR_RESET)"; \
echo "$(COLOR_YELLOW)Или используйте: make git-commit ARGS=\"<сообщение>\"$(COLOR_RESET)"; \
exit 1; \
fi
@$(GIT) commit -m "$(ARGS)"
@echo "$(COLOR_GREEN)✓ Коммит создан$(COLOR_RESET)"
git-branch: ## 🌿 Показать список веток
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Список веток:$(COLOR_RESET)"
@$(GIT) branch -a
# ============================================================================
# Kubernetes команды (подкоманды через make k8s CMD=<cmd>)
# ============================================================================
k8s: ## ☸️ Kubernetes команды (используйте: make k8s CMD=apply|delete|status|logs|shell|contexts|set-context)
@if [ -z "$(CMD)" ]; then \
echo "$(COLOR_BOLD)$(COLOR_CYAN)Kubernetes команды:$(COLOR_RESET)"; \
echo ""; \
echo " $(COLOR_GREEN)make k8s contexts$(COLOR_RESET) - Показать доступные контексты"; \
echo " $(COLOR_GREEN)make k8s set-context [name]$(COLOR_RESET) - Установить контекст"; \
echo " $(COLOR_GREEN)make k8s apply$(COLOR_RESET) - Применить манифесты"; \
echo " $(COLOR_GREEN)make k8s delete$(COLOR_RESET) - Удалить ресурсы"; \
echo " $(COLOR_GREEN)make k8s status$(COLOR_RESET) - Показать статус подов"; \
echo " $(COLOR_GREEN)make k8s logs$(COLOR_RESET) - Показать логи подов"; \
echo " $(COLOR_GREEN)make k8s shell$(COLOR_RESET) - Открыть shell в поде"; \
echo ""; \
if [ -n "$(K8S_CONTEXT)" ]; then \
echo "$(COLOR_CYAN)Текущий контекст: $(COLOR_BOLD)$(K8S_CONTEXT)$(COLOR_RESET)"; \
else \
echo "$(COLOR_YELLOW)⚠ Контекст не установлен$(COLOR_RESET)"; \
fi; \
echo ""; \
echo "$(COLOR_YELLOW)Использование:$(COLOR_RESET)"; \
echo " $(COLOR_CYAN)make k8s CMD=apply$(COLOR_RESET)"; \
echo " $(COLOR_CYAN)make k8s CMD=apply CONTEXT=<контекст>$(COLOR_RESET)"; \
echo " $(COLOR_CYAN)make k8s-apply$(COLOR_RESET) (прямой вызов)"; \
else \
$(MAKE) k8s-$(CMD) CONTEXT="$(CONTEXT)"; \
fi
k8s-contexts: ## 📋 Показать доступные контексты Kubernetes
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Доступные контексты Kubernetes:$(COLOR_RESET)"
@$(KUBECTL) config get-contexts || echo "$(COLOR_YELLOW)⚠ kubectl не установлен или не настроен$(COLOR_RESET)"
@if [ -n "$(K8S_CONTEXT)" ]; then \
echo ""; \
echo "$(COLOR_CYAN)Текущий контекст: $(COLOR_BOLD)$(K8S_CONTEXT)$(COLOR_RESET)"; \
fi
k8s-set-context: ## 🔄 Установить контекст Kubernetes
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Установка контекста Kubernetes...$(COLOR_RESET)"
@if [ -z "$(CONTEXT)" ]; then \
echo "$(COLOR_YELLOW)⚠ Укажите контекст: make k8s set-context CONTEXT=<имя>$(COLOR_RESET)"; \
echo "$(COLOR_YELLOW)Или используйте: make k8s-set-context CONTEXT=<имя>$(COLOR_RESET)"; \
echo ""; \
echo "$(COLOR_CYAN)Доступные контексты:$(COLOR_RESET)"; \
$(KUBECTL) config get-contexts -o name || echo "$(COLOR_YELLOW)⚠ kubectl не установлен$(COLOR_RESET)"; \
exit 1; \
fi
@$(KUBECTL) config use-context $(CONTEXT) || \
(echo "$(COLOR_RED)✗ Ошибка установки контекста$(COLOR_RESET)" && exit 1)
@echo "$(COLOR_GREEN)✓ Контекст установлен: $(CONTEXT)$(COLOR_RESET)"
k8s-apply: ## ✅ Применить манифесты Kubernetes
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Применение манифестов Kubernetes...$(COLOR_RESET)"
@if [ -n "$(CONTEXT)" ]; then \
echo "$(COLOR_CYAN)Использование контекста: $(CONTEXT)$(COLOR_RESET)"; \
$(KUBECTL) --context=$(CONTEXT) apply -f $(K8S_MANIFEST) || \
(echo "$(COLOR_RED)✗ Ошибка применения манифестов$(COLOR_RESET)" && exit 1); \
else \
if [ -n "$(K8S_CONTEXT)" ]; then \
echo "$(COLOR_CYAN)Использование текущего контекста: $(K8S_CONTEXT)$(COLOR_RESET)"; \
fi; \
$(KUBECTL) apply -f $(K8S_MANIFEST) || \
(echo "$(COLOR_RED)✗ Ошибка применения манифестов$(COLOR_RESET)" && exit 1); \
fi
@echo "$(COLOR_GREEN)✓ Манифесты применены$(COLOR_RESET)"
k8s-delete: ## 🗑️ Удалить ресурсы Kubernetes
@echo "$(COLOR_BOLD)$(COLOR_YELLOW)Удаление ресурсов Kubernetes...$(COLOR_RESET)"
@if [ -n "$(CONTEXT)" ]; then \
echo "$(COLOR_CYAN)Использование контекста: $(CONTEXT)$(COLOR_RESET)"; \
$(KUBECTL) --context=$(CONTEXT) delete -f $(K8S_MANIFEST) || \
(echo "$(COLOR_YELLOW)⚠ Ресурсы не найдены или уже удалены$(COLOR_RESET)"); \
else \
if [ -n "$(K8S_CONTEXT)" ]; then \
echo "$(COLOR_CYAN)Использование текущего контекста: $(K8S_CONTEXT)$(COLOR_RESET)"; \
fi; \
$(KUBECTL) delete -f $(K8S_MANIFEST) || \
(echo "$(COLOR_YELLOW)⚠ Ресурсы не найдены или уже удалены$(COLOR_RESET)"); \
fi
@echo "$(COLOR_GREEN)✓ Ресурсы удалены$(COLOR_RESET)"
k8s-status: ## 📊 Показать статус подов Kubernetes
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Статус подов Kubernetes:$(COLOR_RESET)"
@if [ -n "$(CONTEXT)" ]; then \
$(KUBECTL) --context=$(CONTEXT) get pods -n $(K8S_NAMESPACE) || \
(echo "$(COLOR_YELLOW)⚠ Поды не найдены$(COLOR_RESET)"); \
else \
$(KUBECTL) get pods -n $(K8S_NAMESPACE) || \
(echo "$(COLOR_YELLOW)⚠ Поды не найдены$(COLOR_RESET)"); \
fi
k8s-logs: ## 📋 Показать логи подов Kubernetes
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Просмотр логов подов Kubernetes...$(COLOR_RESET)"
@if [ -n "$(CONTEXT)" ]; then \
POD=$$($(KUBECTL) --context=$(CONTEXT) get pods -n $(K8S_NAMESPACE) -l app=$(APP_NAME) -o jsonpath='{.items[0].metadata.name}' 2>/dev/null); \
else \
POD=$$($(KUBECTL) get pods -n $(K8S_NAMESPACE) -l app=$(APP_NAME) -o jsonpath='{.items[0].metadata.name}' 2>/dev/null); \
fi; \
if [ -z "$$POD" ]; then \
echo "$(COLOR_YELLOW)⚠ Поды не найдены$(COLOR_RESET)"; \
exit 1; \
fi; \
echo "$(COLOR_CYAN)Просмотр логов пода: $$POD$(COLOR_RESET)"; \
if [ -n "$(CONTEXT)" ]; then \
$(KUBECTL) --context=$(CONTEXT) logs -f -n $(K8S_NAMESPACE) $$POD --tail=50; \
else \
$(KUBECTL) logs -f -n $(K8S_NAMESPACE) $$POD --tail=50; \
fi
k8s-shell: ## 🐚 Открыть shell в поде Kubernetes
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Открытие shell в поде Kubernetes...$(COLOR_RESET)"
@if [ -n "$(CONTEXT)" ]; then \
POD=$$($(KUBECTL) --context=$(CONTEXT) get pods -n $(K8S_NAMESPACE) -l app=$(APP_NAME) -o jsonpath='{.items[0].metadata.name}' 2>/dev/null); \
else \
POD=$$($(KUBECTL) get pods -n $(K8S_NAMESPACE) -l app=$(APP_NAME) -o jsonpath='{.items[0].metadata.name}' 2>/dev/null); \
fi; \
if [ -z "$$POD" ]; then \
echo "$(COLOR_YELLOW)⚠ Поды не найдены$(COLOR_RESET)"; \
exit 1; \
fi; \
echo "$(COLOR_CYAN)Открытие shell в поде: $$POD$(COLOR_RESET)"; \
clear || true; \
if [ -n "$(CONTEXT)" ]; then \
$(KUBECTL) --context=$(CONTEXT) exec -it -n $(K8S_NAMESPACE) $$POD -- /bin/bash || \
$(KUBECTL) --context=$(CONTEXT) exec -it -n $(K8S_NAMESPACE) $$POD -- /bin/sh; \
else \
$(KUBECTL) exec -it -n $(K8S_NAMESPACE) $$POD -- /bin/bash || \
$(KUBECTL) exec -it -n $(K8S_NAMESPACE) $$POD -- /bin/sh; \
fi
# ============================================================================
# Env команды (подкоманды через make env CMD=<cmd>)
# ============================================================================
env: ## 🔐 Env команды (используйте: make env CMD=check|create|create-force)
@if [ -z "$(CMD)" ]; then \
echo "$(COLOR_BOLD)$(COLOR_CYAN)Env команды:$(COLOR_RESET)"; \
echo ""; \
echo " $(COLOR_GREEN)make env check$(COLOR_RESET) - Проверить наличие .env файла"; \
echo " $(COLOR_GREEN)make env create$(COLOR_RESET) - Создать .env файл из env.example"; \
echo " $(COLOR_GREEN)make env create-force$(COLOR_RESET) - Принудительно создать .env файл"; \
echo ""; \
echo "$(COLOR_YELLOW)Использование:$(COLOR_RESET)"; \
echo " $(COLOR_CYAN)make env CMD=check$(COLOR_RESET)"; \
echo " $(COLOR_CYAN)make env-check$(COLOR_RESET) (прямой вызов)"; \
else \
$(MAKE) env-$(CMD); \
fi
env-check: ## 🔍 Проверить наличие .env файла
@if [ -f $(ENV_FILE) ]; then \
echo "$(COLOR_GREEN)✓ Файл .env найден$(COLOR_RESET)"; \
else \
echo "$(COLOR_RED)✗ Файл .env не найден$(COLOR_RESET)"; \
echo "$(COLOR_YELLOW)Создайте файл .env на основе env.example$(COLOR_RESET)"; \
echo "$(COLOR_CYAN)Используйте: make env create$(COLOR_RESET)"; \
exit 1; \
fi
env-create: ## 📝 Создать .env файл из env.example
@if [ -f $(ENV_FILE) ]; then \
echo "$(COLOR_YELLOW)⚠ Файл .env уже существует$(COLOR_RESET)"; \
echo "$(COLOR_YELLOW)⚠ Используйте 'make env create-force' для перезаписи$(COLOR_RESET)"; \
exit 1; \
fi
@cp env.example $(ENV_FILE)
@echo "$(COLOR_GREEN)✓ Файл .env создан из env.example$(COLOR_RESET)"
@echo "$(COLOR_YELLOW)Не забудьте отредактировать .env и указать необходимые значения$(COLOR_RESET)"
env-create-force: ## 📝 Принудительно создать .env файл из env.example (перезаписать существующий)
@cp env.example $(ENV_FILE)
@echo "$(COLOR_GREEN)✓ Файл .env создан из env.example (перезаписан)$(COLOR_RESET)"
@echo "$(COLOR_YELLOW)Не забудьте отредактировать .env и указать необходимые значения$(COLOR_RESET)"
# ============================================================================
# Утилиты
# ============================================================================
version: ## 📌 Показать версию проекта
@echo "$(COLOR_BOLD)$(COLOR_CYAN)Версия проекта: $(COLOR_RESET)$(COLOR_GREEN)$(VERSION)$(COLOR_RESET)"
@echo "$(COLOR_BOLD)$(COLOR_CYAN)Тег образа: $(COLOR_RESET)$(COLOR_GREEN)$(TAG)$(COLOR_RESET)"
@echo "$(COLOR_BOLD)$(COLOR_CYAN)Регистр: $(COLOR_RESET)$(COLOR_GREEN)$(REGISTRY)$(COLOR_RESET)"
psql: ## 🗄️ Подключиться к PostgreSQL (если используется)
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Подключение к PostgreSQL...$(COLOR_RESET)"
@$(DOCKER_COMPOSE) exec postgres psql -U postgres || echo "$(COLOR_YELLOW)⚠ PostgreSQL не запущен$(COLOR_RESET)"
redis-cli: ## 🔴 Подключиться к Redis (если используется)
@echo "$(COLOR_BOLD)$(COLOR_BLUE)Подключение к Redis...$(COLOR_RESET)"
@$(DOCKER_COMPOSE) exec redis redis-cli || echo "$(COLOR_YELLOW)⚠ Redis не запущен$(COLOR_RESET)"
# ============================================================================
# Целевые команды по умолчанию
# ============================================================================
.DEFAULT_GOAL := help