openvpn-endpoint-server/server/app/models/endpoint.py

88 lines
3.8 KiB
Python

"""Endpoint model for devices behind gateways."""
from datetime import datetime
from enum import Enum as PyEnum
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Enum, Text
from sqlalchemy.orm import relationship
from ..database import Base
class Protocol(str, PyEnum):
"""Network protocol for endpoint access."""
TCP = "tcp"
UDP = "udp"
class Endpoint(Base):
"""Endpoint model representing a device/service behind a gateway."""
__tablename__ = "endpoints"
id = Column(Integer, primary_key=True, index=True)
gateway_id = Column(Integer, ForeignKey("gateways.id"), nullable=False)
# Endpoint info
name = Column(String(255), nullable=False)
description = Column(Text, nullable=True)
# Network configuration
internal_ip = Column(String(45), nullable=False) # IP in customer network
port = Column(Integer, nullable=False)
protocol = Column(Enum(Protocol), default=Protocol.TCP, nullable=False)
# Application info
application_name = Column(String(100), nullable=True) # e.g., "CoDeSys", "SSH", "HTTP"
application_template_id = Column(Integer, ForeignKey("application_templates.id"), nullable=True)
# Timestamps
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
gateway = relationship("Gateway", back_populates="endpoints")
user_access = relationship("UserEndpointAccess", back_populates="endpoint", cascade="all, delete-orphan")
application_template = relationship("ApplicationTemplate")
connection_logs = relationship("ConnectionLog", back_populates="endpoint")
def __repr__(self):
return f"<Endpoint(id={self.id}, name='{self.name}', ip='{self.internal_ip}:{self.port}')>"
@property
def address(self) -> str:
"""Get full address string."""
return f"{self.internal_ip}:{self.port}"
class ApplicationTemplate(Base):
"""Pre-defined application templates with default ports."""
__tablename__ = "application_templates"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(100), nullable=False, unique=True)
description = Column(Text, nullable=True)
default_port = Column(Integer, nullable=False)
protocol = Column(Enum(Protocol), default=Protocol.TCP, nullable=False)
icon = Column(String(100), nullable=True) # Icon name for client UI
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
def __repr__(self):
return f"<ApplicationTemplate(name='{self.name}', port={self.default_port})>"
# Default application templates to be seeded
DEFAULT_APPLICATION_TEMPLATES = [
{"name": "CoDeSys", "description": "CoDeSys Runtime/Gateway", "default_port": 11740, "protocol": "tcp"},
{"name": "CoDeSys Gateway", "description": "CoDeSys Gateway Service", "default_port": 1217, "protocol": "tcp"},
{"name": "SSH", "description": "Secure Shell", "default_port": 22, "protocol": "tcp"},
{"name": "HTTP", "description": "Web Interface", "default_port": 80, "protocol": "tcp"},
{"name": "HTTPS", "description": "Secure Web Interface", "default_port": 443, "protocol": "tcp"},
{"name": "VNC", "description": "Virtual Network Computing", "default_port": 5900, "protocol": "tcp"},
{"name": "RDP", "description": "Remote Desktop Protocol", "default_port": 3389, "protocol": "tcp"},
{"name": "Modbus TCP", "description": "Modbus over TCP/IP", "default_port": 502, "protocol": "tcp"},
{"name": "OPC UA", "description": "OPC Unified Architecture", "default_port": 4840, "protocol": "tcp"},
{"name": "MQTT", "description": "Message Queue Telemetry Transport", "default_port": 1883, "protocol": "tcp"},
{"name": "S7 Communication", "description": "Siemens S7 Protocol", "default_port": 102, "protocol": "tcp"},
]