Files
DevOpsLab/app/services/deployment_service.py
Сергей Антропов 1fbf9185a2 feat: добавлена пометка типа операции (Build/Push) в истории сборок Dockerfile
- Добавлена колонка 'Тип' во все таблицы истории сборок
- Для push операций отображается registry вместо платформ
- Сохранение пользователя при создании push лога
- Исправлена ошибка с logger в push_docker_image endpoint
- Улучшено отображение истории сборок с визуальными индикаторами
2026-02-15 22:59:02 +03:00

134 lines
5.1 KiB
Python
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.

"""
Сервис для развертывания ролей на реальные серверы
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""
import asyncio
from pathlib import Path
from typing import Optional, AsyncGenerator, Dict, List
from datetime import datetime
from app.core.config import settings
from app.core.ansible_executor import AnsibleExecutor
class DeploymentService:
"""Развертывание ролей на реальные серверы"""
def __init__(self):
self.project_root = settings.PROJECT_ROOT
self.inventory_file = self.project_root / "inventory" / "hosts.ini"
self.deploy_playbook = self.project_root / "roles" / "deploy.yml"
self.ansible_executor = AnsibleExecutor()
async def deploy_role(
self,
role_name: str,
inventory: Optional[str] = None,
limit: Optional[str] = None,
tags: Optional[List[str]] = None,
check: bool = False,
extra_vars: Optional[Dict] = None,
stream: bool = False
) -> AsyncGenerator[str, None]:
"""
Развертывание роли на реальные серверы
Args:
role_name: Имя роли для развертывания
inventory: Путь к inventory файлу (по умолчанию inventory/hosts.ini)
limit: Ограничение на хосты
tags: Список тегов для фильтрации
check: Режим dry-run (--check)
extra_vars: Дополнительные переменные
stream: Если True, возвращает генератор строк
Yields:
Строки вывода команды
"""
# Проверка существования роли
role_path = self.project_root / "roles" / role_name
if not role_path.exists():
yield f"❌ Роль '{role_name}' не найдена\n"
return
# Определение inventory файла
if inventory:
inventory_path = Path(inventory)
if not inventory_path.is_absolute():
inventory_path = self.project_root / inventory_path
else:
inventory_path = self.inventory_file
if not inventory_path.exists():
yield f"❌ Inventory файл '{inventory_path}' не найден\n"
yield "💡 Создайте файл inventory/hosts.ini с вашими серверами\n"
return
# Проверка deploy.yml
if not self.deploy_playbook.exists():
yield f"❌ Playbook '{self.deploy_playbook}' не найден\n"
return
# Формирование тегов
deploy_tags = [role_name]
if tags:
deploy_tags.extend(tags)
yield f"🚀 Развертывание роли '{role_name}' на реальные серверы...\n"
if check:
yield "⚠️ Режим dry-run (--check) - изменения не будут применены\n"
yield f"📋 Inventory: {inventory_path}\n"
if limit:
yield f"📋 Limit: {limit}\n"
yield f"📋 Tags: {', '.join(deploy_tags)}\n\n"
# Запуск ansible-playbook
async for line in self.ansible_executor.run_playbook(
playbook_path=str(self.deploy_playbook),
inventory=str(inventory_path),
tags=deploy_tags,
limit=limit,
check=check,
extra_vars=extra_vars,
stream=True
):
yield line
yield "\n✅ Развертывание завершено\n"
async def dry_run_role(
self,
role_name: str,
inventory: Optional[str] = None,
limit: Optional[str] = None,
stream: bool = False
) -> AsyncGenerator[str, None]:
"""
Dry-run проверка роли на реальных серверах (без изменений)
Args:
role_name: Имя роли
inventory: Путь к inventory файлу
limit: Ограничение на хосты
stream: Если True, возвращает генератор строк
Yields:
Строки вывода команды
"""
yield f"🔍 Dry-run проверка роли '{role_name}' на реальных серверах...\n"
yield "⚠️ Безопасно: не изменяет серверы, только проверяет\n\n"
async for line in self.deploy_role(
role_name=role_name,
inventory=inventory,
limit=limit,
check=True,
stream=True
):
yield line
def detect_log_level(self, line: str) -> str:
"""Определение уровня лога из строки"""
return self.ansible_executor.detect_log_level(line)