# plugins/snmp/models.py from __future__ import annotations from datetime import datetime, timezone from sqlalchemy import JSON, DateTime, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column from steward.core.ids import time_ordered_id from steward.models.base import Base class SnmpDevice(Base): """A device Steward polls over SNMP, edited on the SNMP page. Secrets (the community, the v3 keys) are stored encrypted. The last_* columns are the newest poll's outcome, written by the poller, so a page can say why a device isn't answering without asking the device itself. """ __tablename__ = "snmp_devices" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=time_ordered_id) name: Mapped[str] = mapped_column(String(100), nullable=False, unique=True) address: Mapped[str] = mapped_column(String(255), nullable=False) port: Mapped[int] = mapped_column(Integer, nullable=False, default=161) version: Mapped[str] = mapped_column(String(3), nullable=False, default="2c") community: Mapped[str] = mapped_column(Text, nullable=False, default="") v3_user: Mapped[str] = mapped_column(String(100), nullable=False, default="") v3_auth: Mapped[str] = mapped_column(String(16), nullable=False, default="none") v3_auth_key: Mapped[str] = mapped_column(Text, nullable=False, default="") v3_priv: Mapped[str] = mapped_column(String(16), nullable=False, default="none") v3_priv_key: Mapped[str] = mapped_column(Text, nullable=False, default="") presets: Mapped[list] = mapped_column(JSON, nullable=False, default=list) interfaces: Mapped[str] = mapped_column(String(255), nullable=False, default="") custom: Mapped[str] = mapped_column(Text, nullable=False, default="") host_id: Mapped[str | None] = mapped_column(String(36), nullable=True) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc)) last_polled_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) last_ok_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) last_error: Mapped[str | None] = mapped_column(Text, nullable=True) missing: Mapped[list] = mapped_column(JSON, nullable=False, default=list)