- Добавлена колонка 'Тип' во все таблицы истории сборок - Для push операций отображается registry вместо платформ - Сохранение пользователя при создании push лога - Исправлена ошибка с logger в push_docker_image endpoint - Улучшено отображение истории сборок с визуальными индикаторами
262 lines
11 KiB
Python
262 lines
11 KiB
Python
"""
|
||
Модели базы данных для истории команд и тестов
|
||
Автор: Сергей Антропов
|
||
Сайт: https://devops.org.ru
|
||
"""
|
||
|
||
from sqlalchemy import Column, Integer, String, DateTime, Text, Boolean, JSON, ForeignKey
|
||
from sqlalchemy.orm import relationship
|
||
from datetime import datetime
|
||
|
||
# Импортируем Base из user.py для единообразия
|
||
from app.models.user import Base
|
||
|
||
|
||
class CommandHistory(Base):
|
||
"""История выполнения команд"""
|
||
__tablename__ = "command_history"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
command = Column(String, nullable=False, index=True)
|
||
command_type = Column(String, nullable=False, index=True) # test, deploy, export, import
|
||
role_name = Column(String, index=True)
|
||
preset_name = Column(String)
|
||
status = Column(String, nullable=False) # success, failed, running
|
||
stdout = Column(Text)
|
||
stderr = Column(Text)
|
||
returncode = Column(Integer)
|
||
started_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||
finished_at = Column(DateTime)
|
||
duration = Column(Integer) # в секундах
|
||
user = Column(String)
|
||
extra_data = Column(JSON) # Дополнительные данные
|
||
|
||
# Связи
|
||
test_results = relationship("TestResult", back_populates="command")
|
||
|
||
|
||
class TestResult(Base):
|
||
"""Результаты тестирования ролей"""
|
||
__tablename__ = "test_results"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
command_id = Column(Integer, ForeignKey("command_history.id"), nullable=False)
|
||
role_name = Column(String, nullable=False, index=True)
|
||
preset_name = Column(String, index=True)
|
||
test_type = Column(String) # molecule, lint, syntax
|
||
status = Column(String, nullable=False) # passed, failed, skipped
|
||
duration = Column(Integer) # в секундах
|
||
output = Column(Text)
|
||
error = Column(Text)
|
||
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||
|
||
# Связи
|
||
command = relationship("CommandHistory", back_populates="test_results")
|
||
|
||
|
||
class DeploymentHistory(Base):
|
||
"""История деплоев"""
|
||
__tablename__ = "deployment_history"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
role_name = Column(String, nullable=False, index=True)
|
||
inventory = Column(String)
|
||
hosts = Column(JSON) # Список хостов
|
||
status = Column(String, nullable=False) # success, failed, running
|
||
started_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||
finished_at = Column(DateTime)
|
||
duration = Column(Integer)
|
||
output = Column(Text)
|
||
error = Column(Text)
|
||
user = Column(String)
|
||
extra_data = Column(JSON)
|
||
|
||
|
||
class ExportHistory(Base):
|
||
"""История экспорта ролей"""
|
||
__tablename__ = "export_history"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
role_name = Column(String, nullable=False, index=True)
|
||
repo_url = Column(String, nullable=False)
|
||
branch = Column(String)
|
||
version = Column(String)
|
||
commit_hash = Column(String)
|
||
status = Column(String, nullable=False) # success, failed
|
||
started_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||
finished_at = Column(DateTime)
|
||
user = Column(String)
|
||
extra_data = Column(JSON)
|
||
|
||
|
||
class ImportHistory(Base):
|
||
"""История импорта ролей"""
|
||
__tablename__ = "import_history"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
role_name = Column(String, nullable=False, index=True)
|
||
source_type = Column(String, nullable=False) # git, galaxy
|
||
source_url = Column(String)
|
||
status = Column(String, nullable=False) # success, failed
|
||
started_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||
finished_at = Column(DateTime)
|
||
user = Column(String)
|
||
extra_data = Column(JSON)
|
||
|
||
|
||
class Playbook(Base):
|
||
"""Playbook - объединение ролей для тестирования и деплоя"""
|
||
__tablename__ = "playbooks"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
name = Column(String, unique=True, nullable=False, index=True)
|
||
description = Column(Text)
|
||
content = Column(Text, nullable=False) # YAML содержимое playbook
|
||
roles = Column(JSON, nullable=False) # Список ролей в playbook
|
||
variables = Column(JSON) # Переменные для playbook
|
||
inventory = Column(Text) # Инвентарь для playbook
|
||
status = Column(String, default="active") # active, archived
|
||
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
|
||
created_by = Column(String)
|
||
updated_by = Column(String)
|
||
extra_data = Column(JSON)
|
||
|
||
# Связи
|
||
test_runs = relationship("PlaybookTestRun", back_populates="playbook")
|
||
deployments = relationship("PlaybookDeployment", back_populates="playbook")
|
||
|
||
|
||
class PlaybookTestRun(Base):
|
||
"""Результаты тестирования playbook"""
|
||
__tablename__ = "playbook_test_runs"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
playbook_id = Column(Integer, ForeignKey("playbooks.id"), nullable=False)
|
||
preset_name = Column(String, index=True)
|
||
status = Column(String, nullable=False) # running, success, failed, cancelled
|
||
started_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||
finished_at = Column(DateTime)
|
||
duration = Column(Integer) # в секундах
|
||
output = Column(Text)
|
||
error = Column(Text)
|
||
returncode = Column(Integer)
|
||
user = Column(String)
|
||
extra_data = Column(JSON)
|
||
|
||
# Связи
|
||
playbook = relationship("Playbook", back_populates="test_runs")
|
||
|
||
|
||
class PlaybookDeployment(Base):
|
||
"""Результаты деплоя playbook"""
|
||
__tablename__ = "playbook_deployments"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
playbook_id = Column(Integer, ForeignKey("playbooks.id"), nullable=False)
|
||
inventory = Column(Text)
|
||
hosts = Column(JSON) # Список хостов
|
||
status = Column(String, nullable=False) # running, success, failed, cancelled
|
||
started_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||
finished_at = Column(DateTime)
|
||
duration = Column(Integer) # в секундах
|
||
output = Column(Text)
|
||
error = Column(Text)
|
||
returncode = Column(Integer)
|
||
user = Column(String)
|
||
extra_data = Column(JSON)
|
||
|
||
# Связи
|
||
playbook = relationship("Playbook", back_populates="deployments")
|
||
|
||
|
||
class Dockerfile(Base):
|
||
"""Dockerfile для образов тестирования"""
|
||
__tablename__ = "dockerfiles"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
name = Column(String, unique=True, nullable=False, index=True) # ubuntu22, centos8, etc.
|
||
description = Column(Text)
|
||
content = Column(Text, nullable=False) # Содержимое Dockerfile
|
||
base_image = Column(String) # Базовый образ
|
||
tags = Column(JSON) # Теги для образа
|
||
platforms = Column(JSON) # Платформы для сборки (по умолчанию: ["linux/amd64", "linux/386", "linux/arm64"])
|
||
status = Column(String, default="active") # active, archived
|
||
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
|
||
created_by = Column(String)
|
||
updated_by = Column(String)
|
||
extra_data = Column(JSON)
|
||
|
||
|
||
class DockerfileBuildLog(Base):
|
||
"""Логи сборки Dockerfile"""
|
||
__tablename__ = "dockerfile_build_logs"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
dockerfile_id = Column(Integer, ForeignKey("dockerfiles.id"), nullable=False, index=True)
|
||
image_name = Column(String, nullable=False, index=True)
|
||
tag = Column(String, default="latest")
|
||
platforms = Column(JSON) # Список платформ
|
||
status = Column(String, nullable=False, default="running") # running, success, failed
|
||
logs = Column(Text) # Полные логи сборки
|
||
started_at = Column(DateTime, default=datetime.utcnow, nullable=False, index=True)
|
||
finished_at = Column(DateTime)
|
||
duration = Column(Integer) # в секундах
|
||
returncode = Column(Integer)
|
||
user = Column(String)
|
||
extra_data = Column(JSON)
|
||
|
||
# Связи
|
||
dockerfile = relationship("Dockerfile", backref="build_logs")
|
||
|
||
|
||
class Role(Base):
|
||
"""Ansible роли"""
|
||
__tablename__ = "roles"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
name = Column(String, unique=True, nullable=False, index=True) # Имя роли
|
||
description = Column(Text) # Описание роли
|
||
content = Column(JSON, nullable=False) # Содержимое роли в виде JSON структуры {file_path: content}
|
||
# Флаги доступа
|
||
is_global = Column(Boolean, default=False, nullable=False, index=True) # Доступно для всех пользователей
|
||
is_personal = Column(Boolean, default=False, nullable=False, index=True) # Личная роль пользователя
|
||
groups = Column(JSON) # Список групп, которым доступна роль (если is_personal=False и is_global=False)
|
||
user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True) # Владелец роли (если is_personal=True)
|
||
# Метаданные
|
||
author = Column(String) # Автор роли
|
||
platforms = Column(JSON) # Поддерживаемые платформы
|
||
galaxy_info = Column(JSON) # Информация для Ansible Galaxy
|
||
status = Column(String, default="active") # active, archived
|
||
created_at = Column(DateTime, default=datetime.utcnow, nullable=False, index=True)
|
||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
|
||
created_by = Column(String)
|
||
updated_by = Column(String)
|
||
extra_data = Column(JSON)
|
||
|
||
# Связи
|
||
user = relationship("User", backref="roles")
|
||
|
||
|
||
class Preset(Base):
|
||
"""Preset для Molecule тестирования"""
|
||
__tablename__ = "presets"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
name = Column(String, unique=True, nullable=False, index=True) # minimal, default, etc.
|
||
category = Column(String, default="main", index=True) # main, k8s
|
||
description = Column(Text) # Описание из комментария #description:
|
||
content = Column(Text, nullable=False) # YAML содержимое preset'а
|
||
docker_network = Column(String) # Имя Docker сети
|
||
hosts = Column(JSON) # Список хостов
|
||
images = Column(JSON) # Словарь образов
|
||
systemd_defaults = Column(JSON) # Настройки systemd
|
||
kind_clusters = Column(JSON) # Kubernetes кластеры (для k8s preset'ов)
|
||
status = Column(String, default="active") # active, archived
|
||
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
|
||
created_by = Column(String)
|
||
updated_by = Column(String)
|
||
extra_data = Column(JSON)
|