The SNMP poll asks each device's sysName in the same GET and keeps it (snmp_003_sys_name). A syslog source told apart by name finds its own address from the SNMP device (reported or given name) or host of that name, so its lines reach the SNMP device's and host's pages again; the edit page gains Device address, which always wins (syslog_004). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
52 lines
2.9 KiB
Python
52 lines
2.9 KiB
Python
# 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.
|
|
`tables` is the rows the poller found in the presets' vendor tables (a
|
|
disk or volume each), as of `tables_at`; `texts` is each state reading's
|
|
newest answer in the device's own word.
|
|
"""
|
|
__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)
|
|
tables: Mapped[dict] = mapped_column(JSON, nullable=False, default=dict)
|
|
tables_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
texts: Mapped[dict] = mapped_column(JSON, nullable=False, default=dict)
|
|
# The name the device reports (sysName), asked with every poll: how a
|
|
# device whose syslog comes through Docker's address is found (#6096).
|
|
sys_name: Mapped[str] = mapped_column(String(255), nullable=False, default="")
|