86 lines
4.3 KiB
Python
86 lines
4.3 KiB
Python
"""Hugin-Anbindung (→ Konzept 7.9): Host der Plattform, Zugang je Workspace, Auswahl und festgeschriebene Pakete je Workspace.
|
|
|
|
Festgeschrieben wird wie in hugin.lock: Version und Prüfsumme aus Hugin, dazu das Paket im
|
|
Quellformat als ZIP und dessen SHA-256. Beim Laden für einen Run wird die Kopie geprüft.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from typing import Any
|
|
|
|
from sqlalchemy import JSON, Boolean, ForeignKey, LargeBinary, String, Text
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.core.database import Base, now
|
|
|
|
|
|
class HuginHost(Base):
|
|
"""Die Hugin-Instanz der Plattform (genau eine Zeile, id 1); pflegt der Plattform-Admin."""
|
|
|
|
__tablename__ = "hugin_host"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
url: Mapped[str] = mapped_column(String(500))
|
|
# new | ok | error, zuletzt geprüft über /readyz (ohne Key)
|
|
status: Mapped[str] = mapped_column(String(16), default="new")
|
|
status_message: Mapped[str] = mapped_column(Text, default="")
|
|
checked: Mapped[datetime | None] = mapped_column(nullable=True)
|
|
updated_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
|
updated: Mapped[datetime] = mapped_column(default=now)
|
|
|
|
|
|
class WorkspaceHugin(Base):
|
|
"""Zugang des Workspace: Integrations-Key (hi_…) seines Tenants; pflegt der Workspace-Admin.
|
|
Tenant und Key-Name meldet Hugin beim Testen (/status); Pflichtpakete kommen aus diesem Tenant."""
|
|
|
|
__tablename__ = "workspace_hugin"
|
|
|
|
workspace_id: Mapped[int] = mapped_column(ForeignKey("workspaces.id", ondelete="CASCADE"), primary_key=True)
|
|
secret: Mapped[str] = mapped_column(Text)
|
|
hint: Mapped[str] = mapped_column(String(8))
|
|
status: Mapped[str] = mapped_column(String(16), default="new")
|
|
status_message: Mapped[str] = mapped_column(Text, default="")
|
|
tenant: Mapped[str] = mapped_column(String(64), default="")
|
|
key_name: Mapped[str] = mapped_column(String(200), default="")
|
|
checked: Mapped[datetime | None] = mapped_column(nullable=True)
|
|
# Letzter Abgleich (Hintergrund oder Admin) und was er fand: Updates, veraltete Pakete, neue oder
|
|
# entfallene Pflichtpakete, neue Hauptversionen. Leer = alles aktuell.
|
|
synced: Mapped[datetime | None] = mapped_column(nullable=True)
|
|
findings: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict)
|
|
updated_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
|
updated: Mapped[datetime] = mapped_column(default=now)
|
|
|
|
|
|
class WorkspaceHuginPackage(Base):
|
|
"""Vom Workspace-Admin gewähltes Paket, wie eine Zeile in .hugin.yaml (z. B. pub-x@stable)."""
|
|
|
|
__tablename__ = "workspace_hugin_packages"
|
|
|
|
workspace_id: Mapped[int] = mapped_column(ForeignKey("workspaces.id", ondelete="CASCADE"), primary_key=True)
|
|
package_id: Mapped[str] = mapped_column(String(64), primary_key=True)
|
|
spec: Mapped[str] = mapped_column(String(32), default="stable")
|
|
added_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
|
added: Mapped[datetime] = mapped_column(default=now)
|
|
|
|
|
|
class WorkspaceHuginLock(Base):
|
|
"""Festgeschriebene Version eines Pakets (gewählt oder Pflicht)."""
|
|
|
|
__tablename__ = "workspace_hugin_locks"
|
|
|
|
workspace_id: Mapped[int] = mapped_column(ForeignKey("workspaces.id", ondelete="CASCADE"), primary_key=True)
|
|
package_id: Mapped[str] = mapped_column(String(64), primary_key=True)
|
|
kind: Mapped[str] = mapped_column(String(16))
|
|
version: Mapped[str] = mapped_column(String(32))
|
|
checksum: Mapped[str] = mapped_column(String(80)) # Prüfsumme der Version in Hugin
|
|
risk: Mapped[str] = mapped_column(String(16))
|
|
mandatory: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
deprecated: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
description: Mapped[str] = mapped_column(Text, default="")
|
|
arguments: Mapped[list[str]] = mapped_column(JSON, default=list)
|
|
# Paket im Quellformat (hugin.yaml und Dateien) und dessen SHA-256, beim Laden geprüft
|
|
archive: Mapped[bytes] = mapped_column(LargeBinary)
|
|
archive_sha256: Mapped[str] = mapped_column(String(64))
|
|
# Leer = wird angeboten; sonst der Grund, warum nicht (z. B. Skripte, Art nicht unterstützt)
|
|
unsupported: Mapped[str] = mapped_column(Text, default="")
|
|
locked_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
|
locked: Mapped[datetime] = mapped_column(default=now)
|