from __future__ import annotations import uuid from datetime import datetime, timezone from sqlalchemy import Column, DateTime, ForeignKey, JSON, String, Table from sqlalchemy.orm import Mapped, mapped_column, relationship from .base import Base ansible_target_groups = Table( "ansible_target_groups", Base.metadata, Column( "target_id", String(36), ForeignKey("ansible_targets.id", ondelete="CASCADE"), primary_key=True, ), Column( "group_id", String(36), ForeignKey("ansible_groups.id", ondelete="CASCADE"), primary_key=True, ), ) class AnsibleTarget(Base): __tablename__ = "ansible_targets" id: Mapped[str] = mapped_column( String(36), primary_key=True, default=lambda: str(uuid.uuid4()) ) name: Mapped[str] = mapped_column(String(128), nullable=False, unique=True) address: Mapped[str] = mapped_column(String(255), nullable=False) ansible_vars: Mapped[dict] = mapped_column(JSON, nullable=False, default=dict) host_id: Mapped[str | None] = mapped_column( String(36), ForeignKey("hosts.id", ondelete="SET NULL"), nullable=True ) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc), ) groups: Mapped[list["AnsibleGroup"]] = relationship( "AnsibleGroup", secondary=ansible_target_groups, back_populates="targets", lazy="select", ) class AnsibleGroup(Base): __tablename__ = "ansible_groups" id: Mapped[str] = mapped_column( String(36), primary_key=True, default=lambda: str(uuid.uuid4()) ) name: Mapped[str] = mapped_column(String(128), nullable=False, unique=True) ansible_vars: Mapped[dict] = mapped_column(JSON, nullable=False, default=dict) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc), ) targets: Mapped[list["AnsibleTarget"]] = relationship( "AnsibleTarget", secondary=ansible_target_groups, back_populates="groups", lazy="select", )