2026-01-25 18:01:48 +01:00

56 lines
1.9 KiB
Python

"""Push log model (audit trail for SSH commands)"""
from sqlalchemy import Column, String, Integer, ForeignKey, Text, Boolean, Index, Enum
from sqlalchemy.orm import relationship
from app.models.base import BaseModel
import enum
class PushStatus(str, enum.Enum):
"""Push execution status"""
PENDING = "pending"
IN_PROGRESS = "in_progress"
SUCCESS = "success"
FAILED = "failed"
ROLLED_BACK = "rolled_back"
class PushLog(BaseModel):
"""
Audit log for each SSH push attempt.
CRITICAL: All push actions must be logged for compliance and rollback.
"""
__tablename__ = "push_logs"
__table_args__ = (
Index("ix_push_logs_device_id", "device_id"),
Index("ix_push_logs_config_id", "configuration_id"),
)
device_id = Column(Integer, ForeignKey("devices.id"), nullable=False)
configuration_id = Column(Integer, ForeignKey("configurations.id"), nullable=False)
# Commands pushed (plain text for audit)
commands_sent = Column(Text, nullable=False)
# Execution status
status = Column(Enum(PushStatus), default=PushStatus.PENDING, nullable=False)
# Response from device
device_output = Column(Text, nullable=True)
error_message = Column(Text, nullable=True)
# Backup & rollback info
pre_push_backup = Column(Text, nullable=True) # running-config before push
was_rolled_back = Column(Boolean, default=False, nullable=False)
rollback_reason = Column(Text, nullable=True)
# Metadata
pushed_by = Column(String(255), nullable=True) # username
ssh_connection_time_ms = Column(Integer, nullable=True)
# Relationships
device = relationship("Device", back_populates="push_logs")
configuration = relationship("Configuration", back_populates="push_logs")
def __repr__(self):
return f"<PushLog device_id={self.device_id} status={self.status}>"