feat: добавлена пометка типа операции (Build/Push) в истории сборок Dockerfile
- Добавлена колонка 'Тип' во все таблицы истории сборок - Для push операций отображается registry вместо платформ - Сохранение пользователя при создании push лога - Исправлена ошибка с logger в push_docker_image endpoint - Улучшено отображение истории сборок с визуальными индикаторами
This commit is contained in:
187
app/services/playbook_service.py
Normal file
187
app/services/playbook_service.py
Normal file
@@ -0,0 +1,187 @@
|
||||
"""
|
||||
Сервис для работы с playbook
|
||||
Автор: Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
"""
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, update, delete
|
||||
from app.models.database import Playbook, PlaybookTestRun, PlaybookDeployment
|
||||
from typing import Optional, List, Dict
|
||||
import yaml
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PlaybookService:
|
||||
"""Сервис для работы с playbook"""
|
||||
|
||||
@staticmethod
|
||||
async def create_playbook(
|
||||
db: AsyncSession,
|
||||
name: str,
|
||||
roles: List[str],
|
||||
description: Optional[str] = None,
|
||||
variables: Optional[Dict] = None,
|
||||
inventory: Optional[str] = None,
|
||||
created_by: Optional[str] = None
|
||||
) -> Playbook:
|
||||
"""Создание нового playbook"""
|
||||
# Генерация YAML содержимого playbook
|
||||
playbook_content = PlaybookService._generate_playbook_yaml(roles, variables)
|
||||
|
||||
playbook = Playbook(
|
||||
name=name,
|
||||
description=description,
|
||||
content=playbook_content,
|
||||
roles=roles,
|
||||
variables=variables or {},
|
||||
inventory=inventory,
|
||||
created_by=created_by
|
||||
)
|
||||
db.add(playbook)
|
||||
await db.commit()
|
||||
await db.refresh(playbook)
|
||||
return playbook
|
||||
|
||||
@staticmethod
|
||||
async def get_playbook(db: AsyncSession, playbook_id: int) -> Optional[Playbook]:
|
||||
"""Получение playbook по ID"""
|
||||
result = await db.execute(select(Playbook).where(Playbook.id == playbook_id))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@staticmethod
|
||||
async def get_playbook_by_name(db: AsyncSession, name: str) -> Optional[Playbook]:
|
||||
"""Получение playbook по имени"""
|
||||
result = await db.execute(select(Playbook).where(Playbook.name == name))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@staticmethod
|
||||
async def list_playbooks(db: AsyncSession, status: Optional[str] = None) -> List[Playbook]:
|
||||
"""Список всех playbook"""
|
||||
query = select(Playbook)
|
||||
if status:
|
||||
query = query.where(Playbook.status == status)
|
||||
result = await db.execute(query.order_by(Playbook.created_at.desc()))
|
||||
return result.scalars().all()
|
||||
|
||||
@staticmethod
|
||||
async def update_playbook(
|
||||
db: AsyncSession,
|
||||
playbook_id: int,
|
||||
name: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
roles: Optional[List[str]] = None,
|
||||
variables: Optional[Dict] = None,
|
||||
inventory: Optional[str] = None,
|
||||
content: Optional[str] = None,
|
||||
updated_by: Optional[str] = None
|
||||
) -> Optional[Playbook]:
|
||||
"""Обновление playbook"""
|
||||
playbook = await PlaybookService.get_playbook(db, playbook_id)
|
||||
if not playbook:
|
||||
return None
|
||||
|
||||
if name:
|
||||
playbook.name = name
|
||||
if description is not None:
|
||||
playbook.description = description
|
||||
if roles is not None:
|
||||
playbook.roles = roles
|
||||
# Перегенерируем content если изменились роли
|
||||
playbook.content = PlaybookService._generate_playbook_yaml(roles, variables or playbook.variables)
|
||||
if variables is not None:
|
||||
playbook.variables = variables
|
||||
# Перегенерируем content если изменились переменные
|
||||
playbook.content = PlaybookService._generate_playbook_yaml(playbook.roles, variables)
|
||||
if inventory is not None:
|
||||
playbook.inventory = inventory
|
||||
if content is not None:
|
||||
playbook.content = content
|
||||
if updated_by:
|
||||
playbook.updated_by = updated_by
|
||||
|
||||
await db.commit()
|
||||
await db.refresh(playbook)
|
||||
return playbook
|
||||
|
||||
@staticmethod
|
||||
async def delete_playbook(db: AsyncSession, playbook_id: int) -> bool:
|
||||
"""Удаление playbook"""
|
||||
playbook = await PlaybookService.get_playbook(db, playbook_id)
|
||||
if not playbook:
|
||||
return False
|
||||
|
||||
await db.delete(playbook)
|
||||
await db.commit()
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def _generate_playbook_yaml(roles: List[str], variables: Optional[Dict] = None) -> str:
|
||||
"""Генерация YAML содержимого playbook"""
|
||||
playbook_data = {
|
||||
'name': 'Playbook',
|
||||
'hosts': 'all',
|
||||
'become': True,
|
||||
'roles': roles
|
||||
}
|
||||
|
||||
if variables:
|
||||
playbook_data['vars'] = variables
|
||||
|
||||
return yaml.dump([playbook_data], default_flow_style=False, allow_unicode=True)
|
||||
|
||||
@staticmethod
|
||||
async def save_test_run(
|
||||
db: AsyncSession,
|
||||
playbook_id: int,
|
||||
preset_name: Optional[str],
|
||||
status: str,
|
||||
user: Optional[str] = None,
|
||||
output: Optional[str] = None,
|
||||
error: Optional[str] = None,
|
||||
returncode: Optional[int] = None
|
||||
) -> PlaybookTestRun:
|
||||
"""Сохранение результата тестирования playbook"""
|
||||
test_run = PlaybookTestRun(
|
||||
playbook_id=playbook_id,
|
||||
preset_name=preset_name,
|
||||
status=status,
|
||||
output=output,
|
||||
error=error,
|
||||
returncode=returncode,
|
||||
user=user
|
||||
)
|
||||
db.add(test_run)
|
||||
await db.commit()
|
||||
await db.refresh(test_run)
|
||||
return test_run
|
||||
|
||||
@staticmethod
|
||||
async def save_deployment(
|
||||
db: AsyncSession,
|
||||
playbook_id: int,
|
||||
inventory: Optional[str],
|
||||
hosts: Optional[List[str]],
|
||||
status: str,
|
||||
user: Optional[str] = None,
|
||||
output: Optional[str] = None,
|
||||
error: Optional[str] = None,
|
||||
returncode: Optional[int] = None
|
||||
) -> PlaybookDeployment:
|
||||
"""Сохранение результата деплоя playbook"""
|
||||
deployment = PlaybookDeployment(
|
||||
playbook_id=playbook_id,
|
||||
inventory=inventory,
|
||||
hosts=hosts or [],
|
||||
status=status,
|
||||
output=output,
|
||||
error=error,
|
||||
returncode=returncode,
|
||||
user=user
|
||||
)
|
||||
db.add(deployment)
|
||||
await db.commit()
|
||||
await db.refresh(deployment)
|
||||
return deployment
|
||||
Reference in New Issue
Block a user