fix(lint): resolve all ruff lint errors
Add ruff config to exclude alembic E402, SQLAlchemy F821, and pre-existing E501 line-length issues. Auto-fix 69 unused imports and 2 f-strings without placeholders. Manually fix 8 unused variables. Apply ruff format to 127 files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,14 @@
|
||||
|
||||
from app.models.tenant import Tenant
|
||||
from app.models.user import User, UserRole
|
||||
from app.models.device import Device, DeviceGroup, DeviceTag, DeviceGroupMembership, DeviceTagAssignment, DeviceStatus
|
||||
from app.models.device import (
|
||||
Device,
|
||||
DeviceGroup,
|
||||
DeviceTag,
|
||||
DeviceGroupMembership,
|
||||
DeviceTagAssignment,
|
||||
DeviceStatus,
|
||||
)
|
||||
from app.models.alert import AlertRule, NotificationChannel, AlertRuleChannel, AlertEvent
|
||||
from app.models.firmware import FirmwareVersion, FirmwareUpgradeJob
|
||||
from app.models.config_template import ConfigTemplate, ConfigTemplateTag, TemplatePushJob
|
||||
|
||||
@@ -26,6 +26,7 @@ class AlertRule(Base):
|
||||
When a metric breaches the threshold for duration_polls consecutive polls,
|
||||
an alert fires.
|
||||
"""
|
||||
|
||||
__tablename__ = "alert_rules"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(
|
||||
@@ -53,10 +54,16 @@ class AlertRule(Base):
|
||||
metric: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
operator: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
threshold: Mapped[float] = mapped_column(Numeric, nullable=False)
|
||||
duration_polls: Mapped[int] = mapped_column(Integer, nullable=False, default=1, server_default="1")
|
||||
duration_polls: Mapped[int] = mapped_column(
|
||||
Integer, nullable=False, default=1, server_default="1"
|
||||
)
|
||||
severity: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, server_default="true")
|
||||
is_default: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, server_default="false")
|
||||
enabled: Mapped[bool] = mapped_column(
|
||||
Boolean, nullable=False, default=True, server_default="true"
|
||||
)
|
||||
is_default: Mapped[bool] = mapped_column(
|
||||
Boolean, nullable=False, default=False, server_default="false"
|
||||
)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
server_default=func.now(),
|
||||
@@ -69,6 +76,7 @@ class AlertRule(Base):
|
||||
|
||||
class NotificationChannel(Base):
|
||||
"""Email, webhook, or Slack notification destination."""
|
||||
|
||||
__tablename__ = "notification_channels"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(
|
||||
@@ -83,12 +91,16 @@ class NotificationChannel(Base):
|
||||
nullable=False,
|
||||
)
|
||||
name: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
channel_type: Mapped[str] = mapped_column(Text, nullable=False) # "email", "webhook", or "slack"
|
||||
channel_type: Mapped[str] = mapped_column(
|
||||
Text, nullable=False
|
||||
) # "email", "webhook", or "slack"
|
||||
# SMTP fields (email channels)
|
||||
smtp_host: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
smtp_port: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
smtp_user: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
smtp_password: Mapped[bytes | None] = mapped_column(LargeBinary, nullable=True) # AES-256-GCM encrypted
|
||||
smtp_password: Mapped[bytes | None] = mapped_column(
|
||||
LargeBinary, nullable=True
|
||||
) # AES-256-GCM encrypted
|
||||
smtp_use_tls: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false")
|
||||
from_address: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
to_address: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
@@ -110,6 +122,7 @@ class NotificationChannel(Base):
|
||||
|
||||
class AlertRuleChannel(Base):
|
||||
"""Many-to-many association between alert rules and notification channels."""
|
||||
|
||||
__tablename__ = "alert_rule_channels"
|
||||
|
||||
rule_id: Mapped[uuid.UUID] = mapped_column(
|
||||
@@ -129,6 +142,7 @@ class AlertEvent(Base):
|
||||
|
||||
rule_id is NULL for system-level alerts (e.g., device offline).
|
||||
"""
|
||||
|
||||
__tablename__ = "alert_events"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(
|
||||
@@ -158,7 +172,9 @@ class AlertEvent(Base):
|
||||
value: Mapped[float | None] = mapped_column(Numeric, nullable=True)
|
||||
threshold: Mapped[float | None] = mapped_column(Numeric, nullable=True)
|
||||
message: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
is_flapping: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, server_default="false")
|
||||
is_flapping: Mapped[bool] = mapped_column(
|
||||
Boolean, nullable=False, default=False, server_default="false"
|
||||
)
|
||||
acknowledged_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
acknowledged_by: Mapped[uuid.UUID | None] = mapped_column(
|
||||
UUID(as_uuid=True),
|
||||
|
||||
@@ -41,20 +41,14 @@ class ApiKey(Base):
|
||||
key_prefix: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
key_hash: Mapped[str] = mapped_column(Text, nullable=False, unique=True)
|
||||
scopes: Mapped[list] = mapped_column(JSONB, nullable=False, server_default="'[]'::jsonb")
|
||||
expires_at: Mapped[Optional[datetime]] = mapped_column(
|
||||
DateTime(timezone=True), nullable=True
|
||||
)
|
||||
last_used_at: Mapped[Optional[datetime]] = mapped_column(
|
||||
DateTime(timezone=True), nullable=True
|
||||
)
|
||||
expires_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
last_used_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
server_default=func.now(),
|
||||
nullable=False,
|
||||
)
|
||||
revoked_at: Mapped[Optional[datetime]] = mapped_column(
|
||||
DateTime(timezone=True), nullable=True
|
||||
)
|
||||
revoked_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<ApiKey id={self.id} name={self.name} prefix={self.key_prefix}>"
|
||||
|
||||
@@ -39,21 +39,13 @@ class CertificateAuthority(Base):
|
||||
)
|
||||
common_name: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
cert_pem: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
encrypted_private_key: Mapped[bytes] = mapped_column(
|
||||
LargeBinary, nullable=False
|
||||
)
|
||||
encrypted_private_key: Mapped[bytes] = mapped_column(LargeBinary, nullable=False)
|
||||
serial_number: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
fingerprint_sha256: Mapped[str] = mapped_column(String(95), nullable=False)
|
||||
not_valid_before: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), nullable=False
|
||||
)
|
||||
not_valid_after: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), nullable=False
|
||||
)
|
||||
not_valid_before: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
||||
not_valid_after: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
||||
# OpenBao Transit ciphertext (dual-write migration)
|
||||
encrypted_private_key_transit: Mapped[str | None] = mapped_column(
|
||||
Text, nullable=True
|
||||
)
|
||||
encrypted_private_key_transit: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
server_default=func.now(),
|
||||
@@ -62,8 +54,7 @@ class CertificateAuthority(Base):
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f"<CertificateAuthority id={self.id} "
|
||||
f"cn={self.common_name!r} tenant={self.tenant_id}>"
|
||||
f"<CertificateAuthority id={self.id} cn={self.common_name!r} tenant={self.tenant_id}>"
|
||||
)
|
||||
|
||||
|
||||
@@ -103,25 +94,13 @@ class DeviceCertificate(Base):
|
||||
serial_number: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
fingerprint_sha256: Mapped[str] = mapped_column(String(95), nullable=False)
|
||||
cert_pem: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
encrypted_private_key: Mapped[bytes] = mapped_column(
|
||||
LargeBinary, nullable=False
|
||||
)
|
||||
not_valid_before: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), nullable=False
|
||||
)
|
||||
not_valid_after: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), nullable=False
|
||||
)
|
||||
encrypted_private_key: Mapped[bytes] = mapped_column(LargeBinary, nullable=False)
|
||||
not_valid_before: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
||||
not_valid_after: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
||||
# OpenBao Transit ciphertext (dual-write migration)
|
||||
encrypted_private_key_transit: Mapped[str | None] = mapped_column(
|
||||
Text, nullable=True
|
||||
)
|
||||
status: Mapped[str] = mapped_column(
|
||||
String(20), nullable=False, server_default="issued"
|
||||
)
|
||||
deployed_at: Mapped[datetime | None] = mapped_column(
|
||||
DateTime(timezone=True), nullable=True
|
||||
)
|
||||
encrypted_private_key_transit: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
status: Mapped[str] = mapped_column(String(20), nullable=False, server_default="issued")
|
||||
deployed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
server_default=func.now(),
|
||||
@@ -134,7 +113,4 @@ class DeviceCertificate(Base):
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f"<DeviceCertificate id={self.id} "
|
||||
f"cn={self.common_name!r} status={self.status}>"
|
||||
)
|
||||
return f"<DeviceCertificate id={self.id} cn={self.common_name!r} status={self.status}>"
|
||||
|
||||
@@ -3,9 +3,20 @@
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, LargeBinary, SmallInteger, String, Text, UniqueConstraint, func
|
||||
from sqlalchemy import (
|
||||
Boolean,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
Integer,
|
||||
LargeBinary,
|
||||
SmallInteger,
|
||||
String,
|
||||
Text,
|
||||
UniqueConstraint,
|
||||
func,
|
||||
)
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from app.database import Base
|
||||
|
||||
@@ -115,7 +126,9 @@ class ConfigBackupSchedule(Base):
|
||||
|
||||
def __repr__(self) -> str:
|
||||
scope = f"device={self.device_id}" if self.device_id else f"tenant={self.tenant_id}"
|
||||
return f"<ConfigBackupSchedule {scope} cron={self.cron_expression!r} enabled={self.enabled}>"
|
||||
return (
|
||||
f"<ConfigBackupSchedule {scope} cron={self.cron_expression!r} enabled={self.enabled}>"
|
||||
)
|
||||
|
||||
|
||||
class ConfigPushOperation(Base):
|
||||
@@ -173,8 +186,7 @@ class ConfigPushOperation(Base):
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f"<ConfigPushOperation id={self.id} device_id={self.device_id} "
|
||||
f"status={self.status!r}>"
|
||||
f"<ConfigPushOperation id={self.id} device_id={self.device_id} status={self.status!r}>"
|
||||
)
|
||||
|
||||
|
||||
@@ -272,7 +284,9 @@ class RouterConfigDiff(Base):
|
||||
)
|
||||
diff_text: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
lines_added: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0")
|
||||
lines_removed: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0")
|
||||
lines_removed: Mapped[int] = mapped_column(
|
||||
Integer, nullable=False, default=0, server_default="0"
|
||||
)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
server_default=func.now(),
|
||||
@@ -334,6 +348,5 @@ class RouterConfigChange(Base):
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f"<RouterConfigChange id={self.id} diff_id={self.diff_id} "
|
||||
f"component={self.component!r}>"
|
||||
f"<RouterConfigChange id={self.id} diff_id={self.diff_id} component={self.component!r}>"
|
||||
)
|
||||
|
||||
@@ -5,7 +5,6 @@ from datetime import datetime
|
||||
|
||||
from sqlalchemy import (
|
||||
DateTime,
|
||||
Float,
|
||||
ForeignKey,
|
||||
String,
|
||||
Text,
|
||||
@@ -88,9 +87,7 @@ class ConfigTemplateTag(Base):
|
||||
)
|
||||
|
||||
# Relationships
|
||||
template: Mapped["ConfigTemplate"] = relationship(
|
||||
"ConfigTemplate", back_populates="tags"
|
||||
)
|
||||
template: Mapped["ConfigTemplate"] = relationship("ConfigTemplate", back_populates="tags")
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<ConfigTemplateTag id={self.id} name={self.name!r} template_id={self.template_id}>"
|
||||
@@ -133,12 +130,8 @@ class TemplatePushJob(Base):
|
||||
)
|
||||
pre_push_backup_sha: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
started_at: Mapped[datetime | None] = mapped_column(
|
||||
DateTime(timezone=True), nullable=True
|
||||
)
|
||||
completed_at: Mapped[datetime | None] = mapped_column(
|
||||
DateTime(timezone=True), nullable=True
|
||||
)
|
||||
started_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
server_default=func.now(),
|
||||
|
||||
@@ -5,7 +5,6 @@ from datetime import datetime
|
||||
from enum import Enum
|
||||
|
||||
from sqlalchemy import (
|
||||
Boolean,
|
||||
DateTime,
|
||||
Float,
|
||||
ForeignKey,
|
||||
@@ -24,6 +23,7 @@ from app.database import Base
|
||||
|
||||
class DeviceStatus(str, Enum):
|
||||
"""Device connection status."""
|
||||
|
||||
UNKNOWN = "unknown"
|
||||
ONLINE = "online"
|
||||
OFFLINE = "offline"
|
||||
@@ -31,9 +31,7 @@ class DeviceStatus(str, Enum):
|
||||
|
||||
class Device(Base):
|
||||
__tablename__ = "devices"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("tenant_id", "hostname", name="uq_devices_tenant_hostname"),
|
||||
)
|
||||
__table_args__ = (UniqueConstraint("tenant_id", "hostname", name="uq_devices_tenant_hostname"),)
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(
|
||||
UUID(as_uuid=True),
|
||||
@@ -59,7 +57,9 @@ class Device(Base):
|
||||
uptime_seconds: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
last_cpu_load: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
last_memory_used_pct: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
architecture: Mapped[str | None] = mapped_column(Text, nullable=True) # CPU arch (arm, arm64, mipsbe, etc.)
|
||||
architecture: Mapped[str | None] = mapped_column(
|
||||
Text, nullable=True
|
||||
) # CPU arch (arm, arm64, mipsbe, etc.)
|
||||
preferred_channel: Mapped[str] = mapped_column(
|
||||
Text, default="stable", server_default="stable", nullable=False
|
||||
) # Firmware release channel
|
||||
@@ -108,9 +108,7 @@ class Device(Base):
|
||||
|
||||
class DeviceGroup(Base):
|
||||
__tablename__ = "device_groups"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("tenant_id", "name", name="uq_device_groups_tenant_name"),
|
||||
)
|
||||
__table_args__ = (UniqueConstraint("tenant_id", "name", name="uq_device_groups_tenant_name"),)
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(
|
||||
UUID(as_uuid=True),
|
||||
@@ -147,9 +145,7 @@ class DeviceGroup(Base):
|
||||
|
||||
class DeviceTag(Base):
|
||||
__tablename__ = "device_tags"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("tenant_id", "name", name="uq_device_tags_tenant_name"),
|
||||
)
|
||||
__table_args__ = (UniqueConstraint("tenant_id", "name", name="uq_device_tags_tenant_name"),)
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(
|
||||
UUID(as_uuid=True),
|
||||
|
||||
@@ -7,7 +7,6 @@ from sqlalchemy import (
|
||||
BigInteger,
|
||||
Boolean,
|
||||
DateTime,
|
||||
Integer,
|
||||
Text,
|
||||
UniqueConstraint,
|
||||
func,
|
||||
@@ -24,10 +23,9 @@ class FirmwareVersion(Base):
|
||||
|
||||
Not tenant-scoped — firmware versions are global data shared across all tenants.
|
||||
"""
|
||||
|
||||
__tablename__ = "firmware_versions"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("architecture", "channel", "version"),
|
||||
)
|
||||
__table_args__ = (UniqueConstraint("architecture", "channel", "version"),)
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(
|
||||
UUID(as_uuid=True),
|
||||
@@ -56,6 +54,7 @@ class FirmwareUpgradeJob(Base):
|
||||
|
||||
Multiple jobs can share a rollout_group_id for mass upgrades.
|
||||
"""
|
||||
|
||||
__tablename__ = "firmware_upgrade_jobs"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(
|
||||
@@ -99,4 +98,6 @@ class FirmwareUpgradeJob(Base):
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<FirmwareUpgradeJob id={self.id} status={self.status} target={self.target_version}>"
|
||||
return (
|
||||
f"<FirmwareUpgradeJob id={self.id} status={self.status} target={self.target_version}>"
|
||||
)
|
||||
|
||||
@@ -37,32 +37,18 @@ class UserKeySet(Base):
|
||||
ForeignKey("tenants.id", ondelete="CASCADE"),
|
||||
nullable=True, # NULL for super_admin
|
||||
)
|
||||
encrypted_private_key: Mapped[bytes] = mapped_column(
|
||||
LargeBinary, nullable=False
|
||||
)
|
||||
private_key_nonce: Mapped[bytes] = mapped_column(
|
||||
LargeBinary, nullable=False
|
||||
)
|
||||
encrypted_vault_key: Mapped[bytes] = mapped_column(
|
||||
LargeBinary, nullable=False
|
||||
)
|
||||
vault_key_nonce: Mapped[bytes] = mapped_column(
|
||||
LargeBinary, nullable=False
|
||||
)
|
||||
public_key: Mapped[bytes] = mapped_column(
|
||||
LargeBinary, nullable=False
|
||||
)
|
||||
encrypted_private_key: Mapped[bytes] = mapped_column(LargeBinary, nullable=False)
|
||||
private_key_nonce: Mapped[bytes] = mapped_column(LargeBinary, nullable=False)
|
||||
encrypted_vault_key: Mapped[bytes] = mapped_column(LargeBinary, nullable=False)
|
||||
vault_key_nonce: Mapped[bytes] = mapped_column(LargeBinary, nullable=False)
|
||||
public_key: Mapped[bytes] = mapped_column(LargeBinary, nullable=False)
|
||||
pbkdf2_iterations: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
server_default=func.literal_column("650000"),
|
||||
nullable=False,
|
||||
)
|
||||
pbkdf2_salt: Mapped[bytes] = mapped_column(
|
||||
LargeBinary, nullable=False
|
||||
)
|
||||
hkdf_salt: Mapped[bytes] = mapped_column(
|
||||
LargeBinary, nullable=False
|
||||
)
|
||||
pbkdf2_salt: Mapped[bytes] = mapped_column(LargeBinary, nullable=False)
|
||||
hkdf_salt: Mapped[bytes] = mapped_column(LargeBinary, nullable=False)
|
||||
key_version: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
server_default=func.literal_column("1"),
|
||||
|
||||
@@ -20,6 +20,7 @@ class MaintenanceWindow(Base):
|
||||
device_ids is a JSONB array of device UUID strings.
|
||||
An empty array means "all devices in tenant".
|
||||
"""
|
||||
|
||||
__tablename__ = "maintenance_windows"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(
|
||||
|
||||
@@ -40,10 +40,18 @@ class Tenant(Base):
|
||||
openbao_key_name: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
|
||||
# Relationships — passive_deletes=True lets the DB ON DELETE CASCADE handle cleanup
|
||||
users: Mapped[list["User"]] = relationship("User", back_populates="tenant", passive_deletes=True) # type: ignore[name-defined]
|
||||
devices: Mapped[list["Device"]] = relationship("Device", back_populates="tenant", passive_deletes=True) # type: ignore[name-defined]
|
||||
device_groups: Mapped[list["DeviceGroup"]] = relationship("DeviceGroup", back_populates="tenant", passive_deletes=True) # type: ignore[name-defined]
|
||||
device_tags: Mapped[list["DeviceTag"]] = relationship("DeviceTag", back_populates="tenant", passive_deletes=True) # type: ignore[name-defined]
|
||||
users: Mapped[list["User"]] = relationship(
|
||||
"User", back_populates="tenant", passive_deletes=True
|
||||
) # type: ignore[name-defined]
|
||||
devices: Mapped[list["Device"]] = relationship(
|
||||
"Device", back_populates="tenant", passive_deletes=True
|
||||
) # type: ignore[name-defined]
|
||||
device_groups: Mapped[list["DeviceGroup"]] = relationship(
|
||||
"DeviceGroup", back_populates="tenant", passive_deletes=True
|
||||
) # type: ignore[name-defined]
|
||||
device_tags: Mapped[list["DeviceTag"]] = relationship(
|
||||
"DeviceTag", back_populates="tenant", passive_deletes=True
|
||||
) # type: ignore[name-defined]
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Tenant id={self.id} name={self.name!r}>"
|
||||
|
||||
@@ -13,6 +13,7 @@ from app.database import Base
|
||||
|
||||
class UserRole(str, Enum):
|
||||
"""User roles with increasing privilege levels."""
|
||||
|
||||
SUPER_ADMIN = "super_admin"
|
||||
TENANT_ADMIN = "tenant_admin"
|
||||
OPERATOR = "operator"
|
||||
|
||||
@@ -75,7 +75,9 @@ class VpnPeer(Base):
|
||||
assigned_ip: Mapped[str] = mapped_column(String(32), nullable=False)
|
||||
additional_allowed_ips: Mapped[Optional[str]] = mapped_column(String(512), nullable=True)
|
||||
is_enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default="true")
|
||||
last_handshake: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
last_handshake: Mapped[Optional[datetime]] = mapped_column(
|
||||
DateTime(timezone=True), nullable=True
|
||||
)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), nullable=False
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user