feat(17-03): bulk add endpoint and service with credential profile support

- POST /tenants/{tenant_id}/devices/bulk endpoint with rate limiting
- bulk_add_with_profile service validates profile ownership and type compatibility
- Duplicate IP check prevents adding same IP twice in one tenant
- TCP reachability check for RouterOS devices, skipped for SNMP (UDP)
- Per-device result reporting with partial success support
- Device model updated with device_type, snmp_port, snmp_version, snmp_profile_id columns
- Audit logging for bulk add operations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jason Staack
2026-03-21 18:59:24 -05:00
parent 998fff7d01
commit a231b18d69
3 changed files with 219 additions and 0 deletions

View File

@@ -93,6 +93,19 @@ class Device(Base):
nullable=False,
)
# SNMP / device-type columns (migration 039)
device_type: Mapped[str] = mapped_column(
Text, default="routeros", server_default="routeros", nullable=False
)
snmp_port: Mapped[int | None] = mapped_column(Integer, default=161, nullable=True)
snmp_version: Mapped[str | None] = mapped_column(Text, nullable=True)
snmp_profile_id: Mapped[uuid.UUID | None] = mapped_column(
UUID(as_uuid=True),
ForeignKey("snmp_profiles.id", ondelete="SET NULL"),
nullable=True,
index=True,
)
# Relationships
tenant: Mapped["Tenant"] = relationship("Tenant", back_populates="devices") # type: ignore[name-defined]
group_memberships: Mapped[list["DeviceGroupMembership"]] = relationship(