56 lines
1.9 KiB
Python
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}>"
|