from datetime import datetime from typing import Optional, TypedDict from sqlalchemy.orm import Mapped, mapped_column, relationship from app.brm.brn import BRN from app.extensions import db from app.models import AbstractConfiguration, AbstractResource from app.models.base import Group from app.models.types import AwareDateTime from app.util.onion import onion_hostname class OnionDict(TypedDict): Added: str CertExpiry: str CertSans: str Description: str DomainName: str GroupId: int GroupName: str Id: int OnionName: str Updated: str class Onion(AbstractConfiguration): @property def brn(self) -> BRN: return BRN( group_id=self.group_id, product="eotk", provider="*", resource_type="onion", resource_id=self.onion_name ) group_id: Mapped[int] = mapped_column(db.ForeignKey("group.id")) domain_name: Mapped[str] cert_expiry: Mapped[datetime] = mapped_column(AwareDateTime()) cert_sans: Mapped[str] onion_public_key: Mapped[bytes] onion_private_key: Mapped[bytes] tls_public_key: Mapped[bytes] tls_private_key: Mapped[bytes] group = db.relationship("Group", back_populates="onions") @property def onion_name(self) -> str: return onion_hostname(self.onion_public_key) def to_dict(self) -> OnionDict: return { "Added": self.added.isoformat(), "Id": self.id, "CertExpiry": self.cert_expiry.isoformat(), "CertSans": self.cert_sans, "Description": self.description, "DomainName": self.domain_name, "GroupId": self.group_id, "GroupName": self.group.group_name, "OnionName": self.onion_name, "Updated": self.updated.isoformat(), } class Eotk(AbstractResource): group_id: Mapped[int] = mapped_column(db.Integer(), db.ForeignKey("group.id")) instance_id: Mapped[Optional[str]] provider: Mapped[str] region: Mapped[str] group: Mapped[Group] = relationship("Group", back_populates="eotks") @property def brn(self) -> BRN: return BRN( group_id=self.group_id, provider=self.provider, product="eotk", resource_type="instance", resource_id=self.region )